/* Get the data pointer of the specified VRF. If not found, create one. */ void * vrf_info_get (vrf_id_t vrf_id) { struct vrf *vrf = vrf_get (vrf_id); return vrf->info; }
/* Get the interface list of the specified VRF. Create one if not find. */ struct list * vrf_iflist_get (vrf_id_t vrf_id) { struct vrf * vrf = vrf_get (vrf_id); return vrf->iflist; }
static void netlink_vrf_change(struct nlmsghdr *h, struct rtattr *tb, const char *name) { struct ifinfomsg *ifi; struct rtattr *linkinfo[IFLA_INFO_MAX + 1]; struct rtattr *attr[IFLA_VRF_MAX + 1]; struct vrf *vrf; struct zebra_vrf *zvrf; uint32_t nl_table_id; ifi = NLMSG_DATA(h); memset(linkinfo, 0, sizeof linkinfo); parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb); if (!linkinfo[IFLA_INFO_DATA]) { if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( "%s: IFLA_INFO_DATA missing from VRF message: %s", __func__, name); return; } memset(attr, 0, sizeof attr); parse_rtattr_nested(attr, IFLA_VRF_MAX, linkinfo[IFLA_INFO_DATA]); if (!attr[IFLA_VRF_TABLE]) { if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( "%s: IFLA_VRF_TABLE missing from VRF message: %s", __func__, name); return; } nl_table_id = *(uint32_t *)RTA_DATA(attr[IFLA_VRF_TABLE]); if (h->nlmsg_type == RTM_NEWLINK) { if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug("RTM_NEWLINK for VRF %s(%u) table %u", name, ifi->ifi_index, nl_table_id); /* * vrf_get is implied creation if it does not exist */ vrf = vrf_get((vrf_id_t)ifi->ifi_index, name); // It would create vrf if (!vrf) { flog_err(LIB_ERR_INTERFACE, "VRF %s id %u not created", name, ifi->ifi_index); return; } /* * This is the only place that we get the actual kernel table_id * being used. We need it to set the table_id of the routes * we are passing to the kernel.... And to throw some totally * awesome parties. that too. * * At this point we *must* have a zvrf because the vrf_create * callback creates one. We *must* set the table id * before the vrf_enable because of( at the very least ) * static routes being delayed for installation until * during the vrf_enable callbacks. */ zvrf = (struct zebra_vrf *)vrf->info; zvrf->table_id = nl_table_id; /* Enable the created VRF. */ if (!vrf_enable(vrf)) { flog_err(LIB_ERR_INTERFACE, "Failed to enable VRF %s id %u", name, ifi->ifi_index); return; } } else // h->nlmsg_type == RTM_DELLINK { if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug("RTM_DELLINK for VRF %s(%u)", name, ifi->ifi_index); vrf = vrf_lookup_by_id((vrf_id_t)ifi->ifi_index); if (!vrf) { zlog_warn("%s: vrf not found", __func__); return; } vrf_delete(vrf); } }