uint8_t mac[ETH_ADDR_LEN]; /* Current MAC, 0 if unknown. */
uint8_t last_mac[ETH_ADDR_LEN]; /* Last known MAC, 0 if never known */
time_t next_refresh; /* Next time to refresh MAC address. */
+
+ /* Keeping track of the local port's MAC address. */
+ uint8_t local_mac[ETH_ADDR_LEN]; /* Current MAC. */
+ time_t next_local_refresh; /* Next time to refresh MAC address. */
};
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(60, 60);
return mac && eth_addr_equals(mac, dl_addr);
}
+static const uint8_t *
+get_local_mac(struct in_band *ib)
+{
+ time_t now = time_now();
+ if (now >= ib->next_local_refresh) {
+ uint8_t ea[ETH_ADDR_LEN];
+ if (!netdev_nodev_get_etheraddr(netdev_get_name(ib->netdev), ea)) {
+ memcpy(ib->local_mac, ea, ETH_ADDR_LEN);
+ }
+ ib->next_local_refresh = now + 1;
+ }
+ return !eth_addr_is_zero(ib->local_mac) ? ib->local_mac : NULL;
+}
+
+static bool
+is_local_mac(const uint8_t dl_addr[ETH_ADDR_LEN], struct in_band *ib)
+{
+ const uint8_t *local_mac = get_local_mac(ib);
+ return local_mac && eth_addr_equals(dl_addr, local_mac);
+}
+
static void
in_band_learn_mac(struct in_band *in_band,
uint16_t in_port, const uint8_t src_mac[ETH_ADDR_LEN])
if (flow->in_port == ODPP_LOCAL) {
/* Sent by secure channel. */
out_port = mac_learning_lookup(in_band->mac_learning, flow->dl_dst, 0);
- } else if (eth_addr_equals(flow->dl_dst,
- netdev_get_etheraddr(in_band->netdev))) {
+ } else if (is_local_mac(flow->dl_dst, in_band)) {
/* Sent to secure channel. */
out_port = ODPP_LOCAL;
in_band_learn_mac(in_band, flow->in_port, flow->dl_src);
{
struct in_band *in_band = in_band_;
struct in_addr local_ip;
+ const uint8_t *local_mac;
uint32_t controller_ip;
const uint8_t *controller_mac;
- const uint8_t *mac;
- mac = netdev_get_etheraddr(in_band->netdev);
if (netdev_get_in4(in_band->netdev, &local_ip)) {
status_reply_put(sr, "local-ip="IP_FMT, IP_ARGS(&local_ip.s_addr));
}
- status_reply_put(sr, "local-mac="ETH_ADDR_FMT, ETH_ADDR_ARGS(mac));
+ local_mac = get_local_mac(in_band);
+ if (local_mac) {
+ status_reply_put(sr, "local-mac="ETH_ADDR_FMT,
+ ETH_ADDR_ARGS(local_mac));
+ }
controller_ip = rconn_get_ip(in_band->controller);
if (controller_ip) {
in_band->ss_cat = switch_status_register(ss, "in-band",
in_band_status_cb, in_band);
in_band->next_refresh = TIME_MIN;
+ in_band->next_local_refresh = TIME_MIN;
*in_bandp = in_band;
return 0;