From e8e1a4097434114b07c57d183daf617fc2998675 Mon Sep 17 00:00:00 2001 From: Tonghao Zhang Date: Sun, 4 Feb 2018 06:45:38 -0800 Subject: [PATCH] netdev-linux: Report netdev change events when mac changed. When mac addr of ports on bridge has been changed, for example, $ ip link set dev eth0 address 00:11:22:33:44:55 we should reconfigure the datapath id and mac addr of local port. But now openvswitch dont do that as expected. A simple example of how to reproduce it: $ ovs-vsctl add-br br0 $ ifconfig br0 # for example, mac is c6:c6:d7:46:b4:4b $ ip link set dev br0 address 00:11:22:33:44:55 $ ifconfig br0 # mac of br0 will be 00:11:22:33:44:55 then repeat: $ ip link set dev br0 address 00:11:22:33:44:55 $ ifconfig br0 # mac of br0 will be c6:c6:d7:46:b4:4b This patch reports the mac changed event when ports changed, then openvswitch will reconfigure the datapath id and mac addr of local port. Signed-off-by: Tonghao Zhang Signed-off-by: Ben Pfaff --- lib/netdev-linux.c | 3 +++ lib/netlink-notifier.c | 4 +--- lib/netlink-notifier.h | 1 + lib/rtnetlink.c | 9 +++++++++ lib/rtnetlink.h | 1 + 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 6dae7964a89..4e0473cf331 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -747,6 +747,9 @@ netdev_linux_update(struct netdev_linux *dev, dev->etheraddr = change->mac; dev->cache_valid |= VALID_ETHERADDR; dev->ether_addr_error = 0; + + /* The mac addr has been changed, report it now. */ + rtnetlink_report_link(); } dev->ifindex = change->if_index; diff --git a/lib/netlink-notifier.c b/lib/netlink-notifier.c index 3acded418bd..7d8cfffa2af 100644 --- a/lib/netlink-notifier.c +++ b/lib/netlink-notifier.c @@ -32,8 +32,6 @@ VLOG_DEFINE_THIS_MODULE(netlink_notifier); COVERAGE_DEFINE(nln_changed); -static void nln_report(const struct nln *nln, void *change, int group); - struct nln { struct nl_sock *notify_sock; /* Netlink socket. */ struct ovs_list all_notifiers; /* All nln notifiers. */ @@ -225,7 +223,7 @@ nln_wait(struct nln *nln) } } -static void +void nln_report(const struct nln *nln, void *change, int group) { struct nln_notifier *notifier; diff --git a/lib/netlink-notifier.h b/lib/netlink-notifier.h index f6a5150390e..dd0c183de45 100644 --- a/lib/netlink-notifier.h +++ b/lib/netlink-notifier.h @@ -48,4 +48,5 @@ struct nln_notifier *nln_notifier_create(struct nln *, int multicast_group, void nln_notifier_destroy(struct nln_notifier *); void nln_run(struct nln *); void nln_wait(struct nln *); +void nln_report(const struct nln *nln, void *change, int group); #endif /* netlink-notifier.h */ diff --git a/lib/rtnetlink.c b/lib/rtnetlink.c index 5009cd504d7..4d9003b5270 100644 --- a/lib/rtnetlink.c +++ b/lib/rtnetlink.c @@ -180,3 +180,12 @@ rtnetlink_wait(void) nln_wait(nln); } } + +/* Report RTNLGRP_LINK netdev change events. */ +void +rtnetlink_report_link(void) +{ + if (nln) { + nln_report(nln, NULL, RTNLGRP_LINK); + } +} diff --git a/lib/rtnetlink.h b/lib/rtnetlink.h index 91ed4860f0a..518320f735f 100644 --- a/lib/rtnetlink.h +++ b/lib/rtnetlink.h @@ -67,4 +67,5 @@ rtnetlink_notifier_create(rtnetlink_notify_func *, void *aux); void rtnetlink_notifier_destroy(struct nln_notifier *); void rtnetlink_run(void); void rtnetlink_wait(void); +void rtnetlink_report_link(void); #endif /* rtnetlink.h */