<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=us-ascii"><meta name=Generator content="Microsoft Word 12 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:SimSun;
        panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
        {font-family:SimSun;
        panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:"\@SimSun";
        panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=EN-US link=blue vlink=purple><div class=WordSection1><p class=MsoNormal>Below is a patch which allows setting the default route, which is a route with no destination.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>It also fixes a bug with setting the table attribute of a route. It only puts the table<o:p></o:p></p><p class=MsoNormal>attribute in the header if it is less than 256, and if it is greater<o:p></o:p></p><p class=MsoNormal>than 255, sets it as a U32 attribute.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>It changes the scope guessing algorithm to match the one used by iproute2<o:p></o:p></p><p class=MsoNormal>when setting a route.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>It uses the algorithm from iproute2 for setting the table ID for a route if<o:p></o:p></p><p class=MsoNormal>it is not specified by the caller.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>With this patch, I was able to create a default route entry that was identical (or nearly so)<o:p></o:p></p><p class=MsoNormal>to the one created by using iproute2 from the command line.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Jeff<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><span lang=FR-CA>---<o:p></o:p></span></p><p class=MsoNormal><span lang=FR-CA> lib/route/route_obj.c |   70 +++++++++++++++++++++++++++++++++++++++++-------<o:p></o:p></span></p><p class=MsoNormal><span lang=FR-CA> 1 files changed, 59 insertions(+), 11 deletions(-)<o:p></o:p></span></p><p class=MsoNormal><span lang=FR-CA><o:p> </o:p></span></p><p class=MsoNormal><span lang=FR-CA>diff --git a/lib/route/route_obj.c b/lib/route/route_obj.c<o:p></o:p></span></p><p class=MsoNormal><span lang=FR-CA>index ac634ae..da8b595 100644<o:p></o:p></span></p><p class=MsoNormal><span lang=FR-CA>--- a/lib/route/route_obj.c<o:p></o:p></span></p><p class=MsoNormal><span lang=FR-CA>+++ b/lib/route/route_obj.c<o:p></o:p></span></p><p class=MsoNormal><span lang=FR-CA>@@ -779,6 +779,26 @@ int rtnl_route_guess_scope(struct rtnl_route *route)<o:p></o:p></span></p><p class=MsoNormal><span lang=FR-CA> <o:p></o:p></span></p><p class=MsoNormal><span lang=FR-CA> </span>/** @} */<o:p></o:p></p><p class=MsoNormal> <o:p></o:p></p><p class=MsoNormal>+static void adjust_scope(struct rtmsg *rtmsg, uint16_t cmd, int nexthop)<o:p></o:p></p><p class=MsoNormal>+{<o:p></o:p></p><p class=MsoNormal>+        if (rtmsg->rtm_type == RTN_LOCAL ||<o:p></o:p></p><p class=MsoNormal><span lang=DE>+            rtmsg->rtm_type == RTN_NAT)<o:p></o:p></span></p><p class=MsoNormal>+                rtmsg->rtm_scope = RT_SCOPE_HOST;<o:p></o:p></p><p class=MsoNormal>+<o:p></o:p></p><p class=MsoNormal>+        else if (rtmsg->rtm_type == RTN_BROADCAST ||<o:p></o:p></p><p class=MsoNormal>+                 rtmsg->rtm_type == RTN_MULTICAST ||<o:p></o:p></p><p class=MsoNormal>+                 rtmsg->rtm_type == RTN_ANYCAST)<o:p></o:p></p><p class=MsoNormal>+                rtmsg->rtm_scope = RT_SCOPE_LINK;<o:p></o:p></p><p class=MsoNormal>+<o:p></o:p></p><p class=MsoNormal>+        else if (rtmsg->rtm_type == RTN_UNICAST ||<o:p></o:p></p><p class=MsoNormal>+                 rtmsg->rtm_type == RTN_UNSPEC) {<o:p></o:p></p><p class=MsoNormal>+                if (cmd == RTM_DELROUTE)<o:p></o:p></p><p class=MsoNormal>+                        rtmsg->rtm_scope = RT_SCOPE_NOWHERE;<o:p></o:p></p><p class=MsoNormal>+                else if (!nexthop)<o:p></o:p></p><p class=MsoNormal>+                        rtmsg->rtm_scope = RT_SCOPE_LINK;<o:p></o:p></p><p class=MsoNormal>+        }<o:p></o:p></p><p class=MsoNormal>+}<o:p></o:p></p><p class=MsoNormal>+<o:p></o:p></p><p class=MsoNormal> static struct nla_policy route_policy[RTA_MAX+1] = {<o:p></o:p></p><p class=MsoNormal>                <span lang=ES-AR>[RTA_IIF]             = { .type = NLA_U32 },<o:p></o:p></span></p><p class=MsoNormal><span lang=ES-AR>                [RTA_OIF]           = { .type = NLA_U32 },<o:p></o:p></span></p><p class=MsoNormal>@@ -1028,34 +1048,62 @@ int rtnl_route_build_msg(struct nl_msg *msg, struct rtnl_route *route)<o:p></o:p></p><p class=MsoNormal>                struct rtmsg rtmsg = {<o:p></o:p></p><p class=MsoNormal>                                .rtm_family = route->rt_family,<o:p></o:p></p><p class=MsoNormal>                                .rtm_tos = route->rt_tos,<o:p></o:p></p><p class=MsoNormal>-                              .rtm_table = route->rt_table,<o:p></o:p></p><p class=MsoNormal>                                <span lang=PT-BR>.rtm_protocol = route->rt_protocol,<o:p></o:p></span></p><p class=MsoNormal><span lang=PT-BR>                                .rtm_scope = route->rt_scope,<o:p></o:p></span></p><p class=MsoNormal><span lang=PT-BR>                                .rtm_type = route->rt_type,<o:p></o:p></span></p><p class=MsoNormal><span lang=PT-BR>                                .rtm_flags = route->rt_flags,<o:p></o:p></span></p><p class=MsoNormal><span lang=PT-BR>                </span>};<o:p></o:p></p><p class=MsoNormal> <o:p></o:p></p><p class=MsoNormal>-              if (route->rt_dst == NULL)<o:p></o:p></p><p class=MsoNormal>-                              return -NLE_MISSING_ATTR;<o:p></o:p></p><p class=MsoNormal>+              int table_as_attr = 0;<o:p></o:p></p><p class=MsoNormal>+              uint16_t cmd = msg->nm_nlh->nlmsg_type;<o:p></o:p></p><p class=MsoNormal>+<o:p></o:p></p><p class=MsoNormal>+              /* Adjust defaults if necessary */<o:p></o:p></p><p class=MsoNormal>+              if (cmd != RTM_DELROUTE) {<o:p></o:p></p><p class=MsoNormal>+                              if (!(route->ce_mask & ROUTE_ATTR_SCOPE))<o:p></o:p></p><p class=MsoNormal>+                              rtmsg.rtm_scope = RT_SCOPE_UNIVERSE;<o:p></o:p></p><p class=MsoNormal>+              }<o:p></o:p></p><p class=MsoNormal>+<o:p></o:p></p><p class=MsoNormal>+              /* An empty destination is the "default" route */<o:p></o:p></p><p class=MsoNormal>+              if (route->rt_dst)<o:p></o:p></p><p class=MsoNormal>+                              rtmsg.rtm_dst_len = nl_addr_get_prefixlen(route->rt_dst);<o:p></o:p></p><p class=MsoNormal> <o:p></o:p></p><p class=MsoNormal>-              rtmsg.rtm_dst_len = nl_addr_get_prefixlen(route->rt_dst);<o:p></o:p></p><p class=MsoNormal>                if (route->rt_src)<o:p></o:p></p><p class=MsoNormal>                                rtmsg.rtm_src_len = nl_addr_get_prefixlen(route->rt_src);<o:p></o:p></p><p class=MsoNormal> <o:p></o:p></p><p class=MsoNormal>+              /* If scope not explicitly set, adjust based on route type, command and<o:p></o:p></p><p class=MsoNormal>+               * nexthop or gateway */<o:p></o:p></p><p class=MsoNormal>+              if (!(route->ce_mask & ROUTE_ATTR_SCOPE))<o:p></o:p></p><p class=MsoNormal>+                              adjust_scope(&rtmsg, cmd, rtnl_route_get_nnexthops(route));<o:p></o:p></p><p class=MsoNormal>+<o:p></o:p></p><p class=MsoNormal>+              /* If table ID won't fit in 8-bit value of header, add 32-bit<o:p></o:p></p><p class=MsoNormal>+               * attribute below. Is required to allow more than 256 tables. */<o:p></o:p></p><p class=MsoNormal>+              if (route->rt_table < 256)<o:p></o:p></p><p class=MsoNormal>+                              rtmsg.rtm_table = route->rt_table;<o:p></o:p></p><p class=MsoNormal>+              else {<o:p></o:p></p><p class=MsoNormal>+                              rtmsg.rtm_table = RT_TABLE_UNSPEC;<o:p></o:p></p><p class=MsoNormal>+                              table_as_attr = 1;<o:p></o:p></p><p class=MsoNormal>+              }<o:p></o:p></p><p class=MsoNormal> <o:p></o:p></p><p class=MsoNormal>-              if (rtmsg.rtm_scope == RT_SCOPE_NOWHERE)<o:p></o:p></p><p class=MsoNormal>-                              rtmsg.rtm_scope = rtnl_route_guess_scope(route);<o:p></o:p></p><p class=MsoNormal>+              /* If table not explicitly set, adjust from MAIN to LOCAL for these<o:p></o:p></p><p class=MsoNormal>+               * special cases */<o:p></o:p></p><p class=MsoNormal>+              if (!(route->ce_mask & ROUTE_ATTR_TABLE))<o:p></o:p></p><p class=MsoNormal>+                              if (route->rt_type == RTN_LOCAL ||<o:p></o:p></p><p class=MsoNormal>+                                  route->rt_type == RTN_BROADCAST ||<o:p></o:p></p><p class=MsoNormal><span lang=FR-CA>+                                  route->rt_type == RTN_NAT ||<o:p></o:p></span></p><p class=MsoNormal>+                                  route->rt_type == RTN_ANYCAST)<o:p></o:p></p><p class=MsoNormal>+                        rtmsg.rtm_table = RT_TABLE_LOCAL;<o:p></o:p></p><p class=MsoNormal> <o:p></o:p></p><p class=MsoNormal>                if (nlmsg_append(msg, &rtmsg, sizeof(rtmsg), NLMSG_ALIGNTO) < 0)<o:p></o:p></p><p class=MsoNormal>                                goto nla_put_failure;<o:p></o:p></p><p class=MsoNormal> <o:p></o:p></p><p class=MsoNormal>-              /* Additional table attribute replacing the 8bit in the header, was<o:p></o:p></p><p class=MsoNormal>-               * required to allow more than 256 tables. */<o:p></o:p></p><p class=MsoNormal>-              NLA_PUT_U32(msg, RTA_TABLE, route->rt_table);<o:p></o:p></p><p class=MsoNormal>+              if (table_as_attr)<o:p></o:p></p><p class=MsoNormal>+                              NLA_PUT_U32(msg, RTA_TABLE, route->rt_table);<o:p></o:p></p><p class=MsoNormal> <o:p></o:p></p><p class=MsoNormal>-              if (nl_addr_get_len(route->rt_dst))<o:p></o:p></p><p class=MsoNormal>+              if (route->rt_dst && nl_addr_get_len(route->rt_dst))<o:p></o:p></p><p class=MsoNormal>                                NLA_PUT_ADDR(msg, RTA_DST, route->rt_dst);<o:p></o:p></p><p class=MsoNormal>-              NLA_PUT_U32(msg, RTA_PRIORITY, route->rt_prio);<o:p></o:p></p><p class=MsoNormal>+<o:p></o:p></p><p class=MsoNormal>+              if (route->ce_mask & ROUTE_ATTR_PRIO)<o:p></o:p></p><p class=MsoNormal>+                              NLA_PUT_U32(msg, RTA_PRIORITY, route->rt_prio);<o:p></o:p></p><p class=MsoNormal> <o:p></o:p></p><p class=MsoNormal>                if (route->ce_mask & ROUTE_ATTR_SRC)<o:p></o:p></p><p class=MsoNormal>                                NLA_PUT_ADDR(msg, RTA_SRC, route->rt_src);<o:p></o:p></p><p class=MsoNormal>-- <o:p></o:p></p><p class=MsoNormal>1.6.2.5<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><b><span style='font-size:7.5pt;font-family:"Arial","sans-serif"'>Jeffrey M. Bushman</span></b><span style='font-size:7.5pt;font-family:"Arial","sans-serif"'> <span style='color:red'>|</span> <span style='color:gray'>Software Engineer 4</span><br><u><span style='color:blue'><a href="mailto:jbushman@ciena.com"><span style='color:blue'>jbushman@ciena.com</span></a></span></u> <span style='color:red'>|</span><span style='color:purple'> </span><span style='color:gray'>1185 Sanctuary Pkwy, Ste 300 </span><span style='color:red'>|</span><span style='color:purple'> </span><span style='color:gray'>Alpharetta, GA 30009 USA<br>Direct +1.678.867.3572 </span><span style='color:red'>|</span><span style='color:gray'> Fax +1.678.867.5101</span></span><o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p></div></body></html>