static struct vr_bridge_entry * bridge_add(unsigned int router_id, unsigned int vrf, uint8_t *mac, int nh_id) { struct vr_bridge_entry *be; struct vr_bridge_entry_key key; struct vr_nexthop *old_nh; VR_MAC_COPY(key.be_mac, mac); key.be_vrf_id = vrf; be = vr_find_bridge_entry(&key); if (!be) { be = vr_find_free_bridge_entry(vrf, mac); if (!be) return NULL; VR_MAC_COPY(be->be_key.be_mac, mac); be->be_key.be_vrf_id = vrf; be->be_packets = 0; be->be_flags = VR_BE_VALID_FLAG; } /* Un ref the old nexthop */ if (be->be_nh_id != nh_id) { old_nh = be->be_nh; be->be_nh = vrouter_get_nexthop(router_id, nh_id); if (be->be_nh) { be->be_nh_id = be->be_nh->nh_id; } else { be->be_nh_id = -1; } if (be->be_flags & VR_BE_MAC_MOVED_FLAG) { be->be_flags &= ~VR_BE_MAC_MOVED_FLAG; } if (old_nh) vrouter_put_nexthop(old_nh); } return be; }
static int __bridge_table_add(struct vr_route_req *rt) { struct vr_bridge_entry *be; struct vr_nexthop *old_nh; struct vr_bridge_entry_key key; VR_MAC_COPY(key.be_mac, rt->rtr_req.rtr_mac); key.be_vrf_id = rt->rtr_req.rtr_vrf_id; be = vr_find_bridge_entry(&key); if (!be) { be = vr_find_free_bridge_entry(rt->rtr_req.rtr_vrf_id, (char *)rt->rtr_req.rtr_mac); if (!be) return -ENOMEM; VR_MAC_COPY(be->be_key.be_mac, rt->rtr_req.rtr_mac); be->be_key.be_vrf_id = rt->rtr_req.rtr_vrf_id; be->be_flags |= VR_BE_FLAG_VALID; } if (be->be_nh != rt->rtr_nh) { /* Un ref the old nexthop */ old_nh = be->be_nh; be->be_nh = vrouter_get_nexthop(rt->rtr_req.rtr_rid, rt->rtr_req.rtr_nh_id); if (old_nh) vrouter_put_nexthop(old_nh); } if (rt->rtr_req.rtr_label_flags & VR_RT_LABEL_VALID_FLAG) { be->be_label = rt->rtr_req.rtr_label; be->be_flags |= VR_BE_FLAG_LABEL_VALID; } return 0; }