diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2019-07-12 07:31:50 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-12 07:31:50 +0200 |
commit | a04285c6b1a53e7b3cf1bd0df341f324592ef1b1 (patch) | |
tree | 8935ceeb28d22c7eb5f5b4e50633911caa626e87 | |
parent | tree-wide: get rid of strappend() (diff) | |
parent | test-network: add tests for route with type local, multicast, anycast, or bro... (diff) | |
download | systemd-a04285c6b1a53e7b3cf1bd0df341f324592ef1b1.tar.xz systemd-a04285c6b1a53e7b3cf1bd0df341f324592ef1b1.zip |
Merge pull request #13031 from yuwata/network-route-type-local-12975-2
network: make Route.Type= support local or friends
-rw-r--r-- | man/systemd.network.xml | 11 | ||||
-rw-r--r-- | src/network/networkd-manager.c | 28 | ||||
-rw-r--r-- | src/network/networkd-route.c | 185 | ||||
-rw-r--r-- | src/network/networkd-route.h | 15 | ||||
-rw-r--r-- | test/test-network/conf/25-route-static.network | 16 | ||||
-rw-r--r-- | test/test-network/conf/26-bridge-slave-interface-1.network | 3 | ||||
-rw-r--r-- | test/test-network/conf/26-bridge-slave-interface-2.network | 3 | ||||
-rwxr-xr-x | test/test-network/systemd-networkd-tests.py | 33 |
8 files changed, 242 insertions, 52 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 612450dbd8..c9d6fd4d72 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1086,8 +1086,9 @@ <varlistentry> <term><varname>Table=</varname></term> <listitem> - <para>Specifies the routing table identifier to lookup if the rule - selector matches. The table identifier for a route (a number between 1 and 4294967295).</para> + <para>Specifies the routing table identifier to lookup if the rule selector matches. Takes + one of <literal>default</literal>, <literal>main</literal>, and <literal>local</literal>, + or a number between 1 and 4294967295. Defaults to <literal>main</literal>.</para> </listitem> </varlistentry> <varlistentry> @@ -1232,7 +1233,11 @@ <varlistentry> <term><varname>Type=</varname></term> <listitem> - <para>Specifies the type for the route. If <literal>unicast</literal>, a regular route is defined, i.e. a + <para>Specifies the type for the route. Takes one of <literal>unicast</literal>, + <literal>local</literal>, <literal>broadcast</literal>, <literal>anycast</literal>, + <literal>multicast</literal>, <literal>blackhole</literal>, <literal>unreachable</literal>, + <literal>prohibit</literal>, <literal>throw</literal>, <literal>nat</literal>, and + <literal>xresolve</literal>. If <literal>unicast</literal>, a regular route is defined, i.e. a route indicating the path to take to a destination network address. If <literal>blackhole</literal>, packets to the defined route are discarded silently. If <literal>unreachable</literal>, packets to the defined route are discarded and the ICMP message "Host Unreachable" is generated. If <literal>prohibit</literal>, packets diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 33b7ec1d6c..ec3bb47ea6 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -298,7 +298,7 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, vo r = sd_netlink_message_read_u32(message, RTA_OIF, &ifindex); if (r == -ENODATA) { - log_debug("rtnl: received route without ifindex, ignoring"); + log_debug("rtnl: received route message without ifindex, ignoring"); return 0; } else if (r < 0) { log_warning_errno(r, "rtnl: could not get ifindex from route message, ignoring: %m"); @@ -313,7 +313,7 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, vo /* when enumerating we might be out of sync, but we will * get the route again, so just ignore it */ if (!m->enumerating) - log_warning("rtnl: received route for link (%d) we do not know about, ignoring", ifindex); + log_warning("rtnl: received route message for link (%d) we do not know about, ignoring", ifindex); return 0; } @@ -391,43 +391,43 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, vo r = sd_rtnl_message_route_get_dst_prefixlen(message, &dst_prefixlen); if (r < 0) { - log_link_warning_errno(link, r, "rtnl: received route with invalid destination prefixlen, ignoring: %m"); + log_link_warning_errno(link, r, "rtnl: received route message with invalid destination prefixlen, ignoring: %m"); return 0; } r = sd_rtnl_message_route_get_src_prefixlen(message, &src_prefixlen); if (r < 0) { - log_link_warning_errno(link, r, "rtnl: received route with invalid source prefixlen, ignoring: %m"); + log_link_warning_errno(link, r, "rtnl: received route message with invalid source prefixlen, ignoring: %m"); return 0; } r = sd_rtnl_message_route_get_scope(message, &scope); if (r < 0) { - log_link_warning_errno(link, r, "rtnl: received route with invalid scope, ignoring: %m"); + log_link_warning_errno(link, r, "rtnl: received route message with invalid scope, ignoring: %m"); return 0; } r = sd_rtnl_message_route_get_tos(message, &tos); if (r < 0) { - log_link_warning_errno(link, r, "rtnl: received route with invalid tos, ignoring: %m"); + log_link_warning_errno(link, r, "rtnl: received route message with invalid tos, ignoring: %m"); return 0; } r = sd_rtnl_message_route_get_type(message, &rt_type); if (r < 0) { - log_link_warning_errno(link, r, "rtnl: received route with invalid type, ignoring: %m"); + log_link_warning_errno(link, r, "rtnl: received route message with invalid type, ignoring: %m"); return 0; } r = sd_rtnl_message_route_get_table(message, &table); if (r < 0) { - log_link_warning_errno(link, r, "rtnl: received route with invalid table, ignoring: %m"); + log_link_warning_errno(link, r, "rtnl: received route message with invalid table, ignoring: %m"); return 0; } r = sd_netlink_message_read_u32(message, RTA_PRIORITY, &priority); if (r < 0 && r != -ENODATA) { - log_link_warning_errno(link, r, "rtnl: received route with invalid priority, ignoring: %m"); + log_link_warning_errno(link, r, "rtnl: received route message with invalid priority, ignoring: %m"); return 0; } @@ -436,6 +436,8 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, vo if (DEBUG_LOGGING) { _cleanup_free_ char *buf_dst = NULL, *buf_dst_prefixlen = NULL, *buf_src = NULL, *buf_gw = NULL, *buf_prefsrc = NULL; + char buf_scope[ROUTE_SCOPE_STR_MAX], buf_table[ROUTE_TABLE_STR_MAX], + buf_protocol[ROUTE_PROTOCOL_STR_MAX]; if (!in_addr_is_null(family, &dst)) { (void) in_addr_to_string(family, &dst, &buf_dst); @@ -449,10 +451,14 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, vo (void) in_addr_to_string(family, &prefsrc, &buf_prefsrc); log_link_debug(link, - "%s route: dst: %s%s, src: %s, gw: %s, prefsrc: %s", + "%s route: dst: %s%s, src: %s, gw: %s, prefsrc: %s, scope: %s, table: %s, proto: %s, type: %s", type == RTM_DELROUTE ? "Forgetting" : route ? "Updating remembered" : "Remembering", strna(buf_dst), strempty(buf_dst_prefixlen), - strna(buf_src), strna(buf_gw), strna(buf_prefsrc)); + strna(buf_src), strna(buf_gw), strna(buf_prefsrc), + format_route_scope(scope, buf_scope, sizeof buf_scope), + format_route_table(table, buf_table, sizeof buf_table), + format_route_protocol(protocol, buf_protocol, sizeof buf_protocol), + strna(route_type_to_string(rt_type))); } switch (type) { diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index f79d5b2057..ddc0fe279f 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -12,7 +12,9 @@ #include "networkd-route.h" #include "parse-util.h" #include "set.h" +#include "string-table.h" #include "string-util.h" +#include "strxcpyx.h" #include "sysctl-util.h" #include "util.h" @@ -412,6 +414,29 @@ int route_remove(Route *route, Link *link, if (r < 0) return log_link_error_errno(link, r, "Could not create RTM_DELROUTE message: %m"); + if (DEBUG_LOGGING) { + _cleanup_free_ char *dst = NULL, *dst_prefixlen = NULL, *src = NULL, *gw = NULL, *prefsrc = NULL; + char scope[ROUTE_SCOPE_STR_MAX], table[ROUTE_TABLE_STR_MAX], protocol[ROUTE_PROTOCOL_STR_MAX]; + + if (!in_addr_is_null(route->family, &route->dst)) { + (void) in_addr_to_string(route->family, &route->dst, &dst); + (void) asprintf(&dst_prefixlen, "/%u", route->dst_prefixlen); + } + if (!in_addr_is_null(route->family, &route->src)) + (void) in_addr_to_string(route->family, &route->src, &src); + if (!in_addr_is_null(route->family, &route->gw)) + (void) in_addr_to_string(route->family, &route->gw, &gw); + if (!in_addr_is_null(route->family, &route->prefsrc)) + (void) in_addr_to_string(route->family, &route->prefsrc, &prefsrc); + + log_link_debug(link, "Removing route: dst: %s%s, src: %s, gw: %s, prefsrc: %s, scope: %s, table: %s, proto: %s, type: %s", + strna(dst), strempty(dst_prefixlen), strna(src), strna(gw), strna(prefsrc), + format_route_scope(route->scope, scope, sizeof(scope)), + format_route_table(route->table, table, sizeof(table)), + format_route_protocol(route->protocol, protocol, sizeof(protocol)), + strna(route_type_to_string(route->type))); + } + if (in_addr_is_null(route->family, &route->gw) == 0) { r = netlink_message_append_in_addr_union(req, RTA_GATEWAY, route->family, &route->gw); if (r < 0) @@ -513,6 +538,7 @@ int route_configure( if (DEBUG_LOGGING) { _cleanup_free_ char *dst = NULL, *dst_prefixlen = NULL, *src = NULL, *gw = NULL, *prefsrc = NULL; + char scope[ROUTE_SCOPE_STR_MAX], table[ROUTE_TABLE_STR_MAX], protocol[ROUTE_PROTOCOL_STR_MAX]; if (!in_addr_is_null(route->family, &route->dst)) { (void) in_addr_to_string(route->family, &route->dst, &dst); @@ -525,8 +551,12 @@ int route_configure( if (!in_addr_is_null(route->family, &route->prefsrc)) (void) in_addr_to_string(route->family, &route->prefsrc, &prefsrc); - log_link_debug(link, "Configuring route: dst: %s%s, src: %s, gw: %s, prefsrc: %s", - strna(dst), strempty(dst_prefixlen), strna(src), strna(gw), strna(prefsrc)); + log_link_debug(link, "Configuring route: dst: %s%s, src: %s, gw: %s, prefsrc: %s, scope: %s, table: %s, proto: %s, type: %s", + strna(dst), strempty(dst_prefixlen), strna(src), strna(gw), strna(prefsrc), + format_route_scope(route->scope, scope, sizeof(scope)), + format_route_table(route->table, table, sizeof(table)), + format_route_protocol(route->protocol, protocol, sizeof(protocol)), + strna(route_type_to_string(route->type))); } r = sd_rtnl_message_new_route(link->manager->rtnl, &req, @@ -718,6 +748,8 @@ int network_add_ipv4ll_route(Network *network) { n->family = AF_INET; n->dst_prefixlen = 16; n->scope = RT_SCOPE_LINK; + n->scope_set = true; + n->table_set = true; n->priority = IPV4LL_ROUTE_METRIC; n->protocol = RTPROT_STATIC; @@ -749,6 +781,88 @@ int network_add_default_route_on_device(Network *network) { return 0; } +static const char * const route_type_table[__RTN_MAX] = { + [RTN_UNICAST] = "unicast", + [RTN_LOCAL] = "local", + [RTN_BROADCAST] = "broadcast", + [RTN_ANYCAST] = "anycast", + [RTN_MULTICAST] = "multicast", + [RTN_BLACKHOLE] = "blackhole", + [RTN_UNREACHABLE] = "unreachable", + [RTN_PROHIBIT] = "prohibit", + [RTN_THROW] = "throw", + [RTN_NAT] = "nat", + [RTN_XRESOLVE] = "xresolve", +}; + +assert_cc(__RTN_MAX <= UCHAR_MAX); +DEFINE_STRING_TABLE_LOOKUP(route_type, int); + +static const char * const route_scope_table[] = { + [RT_SCOPE_UNIVERSE] = "global", + [RT_SCOPE_SITE] = "site", + [RT_SCOPE_LINK] = "link", + [RT_SCOPE_HOST] = "host", + [RT_SCOPE_NOWHERE] = "nowhere", +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP(route_scope, int); + +const char *format_route_scope(int scope, char *buf, size_t size) { + const char *s; + char *p = buf; + + s = route_scope_to_string(scope); + if (s) + strpcpy(&p, size, s); + else + strpcpyf(&p, size, "%d", scope); + + return buf; +} + +static const char * const route_table_table[] = { + [RT_TABLE_DEFAULT] = "default", + [RT_TABLE_MAIN] = "main", + [RT_TABLE_LOCAL] = "local", +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP(route_table, int); + +const char *format_route_table(int table, char *buf, size_t size) { + const char *s; + char *p = buf; + + s = route_table_to_string(table); + if (s) + strpcpy(&p, size, s); + else + strpcpyf(&p, size, "%d", table); + + return buf; +} + +static const char * const route_protocol_table[] = { + [RTPROT_KERNEL] = "kernel", + [RTPROT_BOOT] = "boot", + [RTPROT_STATIC] = "static", +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP(route_protocol, int); + +const char *format_route_protocol(int protocol, char *buf, size_t size) { + const char *s; + char *p = buf; + + s = route_protocol_to_string(protocol); + if (s) + strpcpy(&p, size, s); + else + strpcpyf(&p, size, "%d", protocol); + + return buf; +} + int config_parse_gateway( const char *unit, const char *filename, @@ -948,17 +1062,14 @@ int config_parse_route_scope( if (r < 0) return r; - if (streq(rvalue, "host")) - n->scope = RT_SCOPE_HOST; - else if (streq(rvalue, "link")) - n->scope = RT_SCOPE_LINK; - else if (streq(rvalue, "global")) - n->scope = RT_SCOPE_UNIVERSE; - else { + r = route_scope_from_string(rvalue); + if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, 0, "Unknown route scope: %s", rvalue); return 0; } + n->scope = r; + n->scope_set = true; TAKE_PTR(n); return 0; } @@ -989,13 +1100,19 @@ int config_parse_route_table( if (r < 0) return r; - r = safe_atou32(rvalue, &n->table); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Could not parse route table number \"%s\", ignoring assignment: %m", rvalue); - return 0; + r = route_table_from_string(rvalue); + if (r >= 0) + n->table = r; + else { + r = safe_atou32(rvalue, &n->table); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Could not parse route table number \"%s\", ignoring assignment: %m", rvalue); + return 0; + } } + n->table_set = true; TAKE_PTR(n); return 0; } @@ -1094,12 +1211,9 @@ int config_parse_route_protocol( if (r < 0) return r; - if (streq(rvalue, "kernel")) - n->protocol = RTPROT_KERNEL; - else if (streq(rvalue, "boot")) - n->protocol = RTPROT_BOOT; - else if (streq(rvalue, "static")) - n->protocol = RTPROT_STATIC; + r = route_protocol_from_string(rvalue); + if (r >= 0) + n->protocol = r; else { r = safe_atou8(rvalue , &n->protocol); if (r < 0) { @@ -1127,28 +1241,21 @@ int config_parse_route_type( Network *network = userdata; _cleanup_(route_free_or_set_invalidp) Route *n = NULL; - int r; + int t, r; r = route_new_static(network, filename, section_line, &n); if (r < 0) return r; - if (streq(rvalue, "unicast")) - n->type = RTN_UNICAST; - else if (streq(rvalue, "blackhole")) - n->type = RTN_BLACKHOLE; - else if (streq(rvalue, "unreachable")) - n->type = RTN_UNREACHABLE; - else if (streq(rvalue, "prohibit")) - n->type = RTN_PROHIBIT; - else if (streq(rvalue, "throw")) - n->type = RTN_THROW; - else { - log_syntax(unit, LOG_ERR, filename, line, r, + t = route_type_from_string(rvalue); + if (t < 0) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Could not parse route type \"%s\", ignoring assignment: %m", rvalue); return 0; } + n->type = (unsigned char) t; + TAKE_PTR(n); return 0; } @@ -1366,6 +1473,18 @@ int route_section_verify(Route *route, Network *network) { route->section->filename, route->section->line); } + if (route->family != AF_INET6) { + if (!route->table_set && IN_SET(route->type, RTN_LOCAL, RTN_BROADCAST, RTN_ANYCAST, RTN_NAT)) + route->table = RT_TABLE_LOCAL; + + if (!route->scope_set) { + if (IN_SET(route->type, RTN_LOCAL, RTN_NAT)) + route->scope = RT_SCOPE_HOST; + else if (IN_SET(route->type, RTN_BROADCAST, RTN_ANYCAST)) + route->scope = RT_SCOPE_LINK; + } + } + if (network->n_static_addresses == 0 && in_addr_is_null(route->family, &route->gw) == 0 && route->gateway_onlink < 0) { diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h index 3c0ac896ae..86a7a82617 100644 --- a/src/network/networkd-route.h +++ b/src/network/networkd-route.h @@ -2,6 +2,7 @@ #pragma once #include "conf-parser.h" +#include "macro.h" typedef struct Route Route; typedef struct NetworkConfigSection NetworkConfigSection; @@ -23,11 +24,13 @@ struct Route { unsigned char dst_prefixlen; unsigned char src_prefixlen; unsigned char scope; + bool scope_set; unsigned char protocol; /* RTPROT_* */ unsigned char type; /* RTN_* */ unsigned char tos; uint32_t priority; /* note that ip(8) calls this 'metric' */ uint32_t table; + bool table_set; uint32_t mtu; uint32_t initcwnd; uint32_t initrwnd; @@ -65,6 +68,18 @@ DEFINE_NETWORK_SECTION_FUNCTIONS(Route, route_free); int network_add_ipv4ll_route(Network *network); int network_add_default_route_on_device(Network *network); +const char* route_type_to_string(int t) _const_; +int route_type_from_string(const char *s) _pure_; + +#define ROUTE_SCOPE_STR_MAX CONST_MAX(DECIMAL_STR_MAX(int), STRLEN("nowhere") + 1) +const char *format_route_scope(int scope, char *buf, size_t size); + +#define ROUTE_TABLE_STR_MAX CONST_MAX(DECIMAL_STR_MAX(int), STRLEN("default") + 1) +const char *format_route_table(int table, char *buf, size_t size); + +#define ROUTE_PROTOCOL_STR_MAX CONST_MAX(DECIMAL_STR_MAX(int), STRLEN("kernel") + 1) +const char *format_route_protocol(int protocol, char *buf, size_t size); + CONFIG_PARSER_PROTOTYPE(config_parse_gateway); CONFIG_PARSER_PROTOTYPE(config_parse_preferred_src); CONFIG_PARSER_PROTOTYPE(config_parse_destination); diff --git a/test/test-network/conf/25-route-static.network b/test/test-network/conf/25-route-static.network index 9e12480a65..9c8269e3b8 100644 --- a/test/test-network/conf/25-route-static.network +++ b/test/test-network/conf/25-route-static.network @@ -46,3 +46,19 @@ Destination=202.54.1.3 [Route] Type=prohibit Destination=202.54.1.4 + +[Route] +Type=local +Destination=149.10.123.1 + +[Route] +Type=anycast +Destination=149.10.123.2 + +[Route] +Type=broadcast +Destination=149.10.123.3 + +[Route] +Type=multicast +Destination=149.10.123.4 diff --git a/test/test-network/conf/26-bridge-slave-interface-1.network b/test/test-network/conf/26-bridge-slave-interface-1.network index 1f8c5b5648..6aed178525 100644 --- a/test/test-network/conf/26-bridge-slave-interface-1.network +++ b/test/test-network/conf/26-bridge-slave-interface-1.network @@ -13,3 +13,6 @@ MulticastFlood = false MulticastToUnicast = true NeighborSuppression = true Learning = false +Priority = 23 +UseBPDU = true +AllowPortToBeRoot=true diff --git a/test/test-network/conf/26-bridge-slave-interface-2.network b/test/test-network/conf/26-bridge-slave-interface-2.network index 45ec2de999..5fccfec5d1 100644 --- a/test/test-network/conf/26-bridge-slave-interface-2.network +++ b/test/test-network/conf/26-bridge-slave-interface-2.network @@ -3,3 +3,6 @@ Name=test1 [Network] Bridge=bridge99 + +[Bridge] +Priority=0 diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 399824af5c..e396af05da 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -1552,14 +1552,18 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities): start_networkd() wait_online(['dummy98:routable']) + print('### ip -6 route show dev dummy98') output = check_output('ip -6 route show dev dummy98') print(output) self.assertRegex(output, '2001:1234:5:8fff:ff:ff:ff:ff proto static') self.assertRegex(output, '2001:1234:5:8f63::1 proto kernel') + print('### ip -6 route show dev dummy98 default') output = check_output('ip -6 route show dev dummy98 default') + print(output) self.assertRegex(output, 'default via 2001:1234:5:8fff:ff:ff:ff:ff proto static metric 1024 pref medium') + print('### ip -4 route show dev dummy98') output = check_output('ip -4 route show dev dummy98') print(output) self.assertRegex(output, '149.10.124.48/28 proto kernel scope link src 149.10.124.58') @@ -1567,20 +1571,33 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities): self.assertRegex(output, '169.254.0.0/16 proto static scope link metric 2048') self.assertRegex(output, '192.168.1.1 proto static initcwnd 20') self.assertRegex(output, '192.168.1.2 proto static initrwnd 30') + self.assertRegex(output, 'multicast 149.10.123.4 proto static') + print('### ip -4 route show dev dummy98 default') output = check_output('ip -4 route show dev dummy98 default') + print(output) self.assertRegex(output, 'default via 149.10.125.65 proto static onlink') self.assertRegex(output, 'default via 149.10.124.64 proto static') self.assertRegex(output, 'default proto static') + print('### ip -4 route show table local dev dummy98') + output = check_output('ip -4 route show table local dev dummy98') + print(output) + self.assertRegex(output, 'local 149.10.123.1 proto static scope host') + self.assertRegex(output, 'anycast 149.10.123.2 proto static scope link') + self.assertRegex(output, 'broadcast 149.10.123.3 proto static scope link') + + print('### ip route show type blackhole') output = check_output('ip route show type blackhole') print(output) self.assertRegex(output, 'blackhole 202.54.1.2 proto static') + print('### ip route show type unreachable') output = check_output('ip route show type unreachable') print(output) self.assertRegex(output, 'unreachable 202.54.1.3 proto static') + print('### ip route show type prohibit') output = check_output('ip route show type prohibit') print(output) self.assertRegex(output, 'prohibit 202.54.1.4 proto static') @@ -2007,18 +2024,24 @@ class NetworkdBridgeTests(unittest.TestCase, Utilities): output = check_output('bridge -d link show dummy98') print(output) - self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'hairpin_mode'), '1') self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'path_cost'), '400') + self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'hairpin_mode'), '1') + self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'multicast_fast_leave'), '1') self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'unicast_flood'), '1') self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'multicast_flood'), '0') - self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'multicast_fast_leave'), '1') + # CONFIG_BRIDGE_IGMP_SNOOPING=y + if (os.path.exists('/sys/devices/virtual/net/bridge00/lower_dummy98/brport/multicast_to_unicast')): + self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'multicast_to_unicast'), '1') if (os.path.exists('/sys/devices/virtual/net/bridge99/lower_dummy98/brport/neigh_suppress')): self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'neigh_suppress'), '1') self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'learning'), '0') + self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'priority'), '23') + self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'bpdu_guard'), '1') + self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'root_block'), '1') - # CONFIG_BRIDGE_IGMP_SNOOPING=y - if (os.path.exists('/sys/devices/virtual/net/bridge00/lower_dummy98/brport/multicast_to_unicast')): - self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'multicast_to_unicast'), '1') + output = check_output('bridge -d link show test1') + print(output) + self.assertEqual(read_bridge_port_attr('bridge99', 'test1', 'priority'), '0') check_output('ip address add 192.168.0.16/24 dev bridge99') time.sleep(1) |