netifd v2: Fix source routing for IPv4
[project/netifd.git] / system-linux.c
index 83827d5..ed69bef 100644 (file)
@@ -1412,11 +1412,16 @@ static int system_rt(struct device *dev, struct device_route *route, int cmd)
                                rtm.rtm_table = RT_TABLE_LOCAL;
                }
 
-               if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_NAT)
+               if (rtm.rtm_type == RTN_LOCAL || rtm.rtm_type == RTN_NAT) {
                        rtm.rtm_scope = RT_SCOPE_HOST;
-               else if (rtm.rtm_type == RTN_BROADCAST || rtm.rtm_type == RTN_MULTICAST ||
-                       rtm.rtm_type == RTN_ANYCAST)
+               else if (rtm.rtm_type == RTN_BROADCAST || rtm.rtm_type == RTN_MULTICAST ||
+                               rtm.rtm_type == RTN_ANYCAST) {
                        rtm.rtm_scope = RT_SCOPE_LINK;
+               } else if (rtm.rtm_type == RTN_BLACKHOLE || rtm.rtm_type == RTN_UNREACHABLE ||
+                               rtm.rtm_type == RTN_PROHIBIT || rtm.rtm_type == RTN_FAILED_POLICY) {
+                       rtm.rtm_scope = RT_SCOPE_UNIVERSE;
+                       dev = NULL;
+               }
        }
 
        msg = nlmsg_alloc_simple(cmd, flags);
@@ -1428,8 +1433,12 @@ static int system_rt(struct device *dev, struct device_route *route, int cmd)
        if (route->mask)
                nla_put(msg, RTA_DST, alen, &route->addr);
 
-       if (route->sourcemask)
-               nla_put(msg, RTA_SRC, alen, &route->source);
+       if (route->sourcemask) {
+               if (rtm.rtm_family == AF_INET)
+                       nla_put(msg, RTA_PREFSRC, alen, &route->source);
+               else
+                       nla_put(msg, RTA_SRC, alen, &route->source);
+       }
 
        if (route->metric > 0)
                nla_put_u32(msg, RTA_PRIORITY, route->metric);