diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -3880,6 +3880,7 @@ case PRIV_NET_GIF: case PRIV_NET_SETIFVNET: case PRIV_NET_SETIFFIB: + case PRIV_NET_VXLAN: case PRIV_NET_OVPN: case PRIV_NET_ME: case PRIV_NET_WG: diff --git a/sys/net/if_vxlan.c b/sys/net/if_vxlan.c --- a/sys/net/if_vxlan.c +++ b/sys/net/if_vxlan.c @@ -376,6 +376,9 @@ static void vxlan_set_hwcaps(struct vxlan_softc *); static int vxlan_clone_create(struct if_clone *, char *, size_t, struct ifc_data *, struct ifnet **); +#ifdef VIMAGE +static void vxlan_reassign(struct ifnet *, struct vnet *, char *); +#endif static int vxlan_clone_destroy(struct if_clone *, struct ifnet *, uint32_t); static uint32_t vxlan_mac_hash(struct vxlan_softc *, const uint8_t *); @@ -406,21 +409,24 @@ static int vxlan_tunable_int(struct vxlan_softc *, const char *, int); static void vxlan_ifdetach_event(void *, struct ifnet *); -static void vxlan_load(void); -static void vxlan_unload(void); +static void vnet_vxlan_init(const void *); +static void vnet_vxlan_uninit(const void *); static int vxlan_modevent(module_t, int, void *); static const char vxlan_name[] = "vxlan"; static MALLOC_DEFINE(M_VXLAN, vxlan_name, "Virtual eXtensible LAN Interface"); -static struct if_clone *vxlan_cloner; +VNET_DEFINE_STATIC(struct if_clone *, vxlan_cloner); +#define V_vxlan_cloner VNET(vxlan_cloner) -static struct mtx vxlan_list_mtx; -#define VXLAN_LIST_LOCK() mtx_lock(&vxlan_list_mtx) -#define VXLAN_LIST_UNLOCK() mtx_unlock(&vxlan_list_mtx) +VNET_DEFINE_STATIC(struct mtx, vxlan_list_mtx); +#define V_vxlan_list_mtx VNET(vxlan_list_mtx) +#define VXLAN_LIST_LOCK() mtx_lock(&V_vxlan_list_mtx) +#define VXLAN_LIST_UNLOCK() mtx_unlock(&V_vxlan_list_mtx) -static LIST_HEAD(, vxlan_socket) vxlan_socket_list = +VNET_DEFINE_STATIC(LIST_HEAD(, vxlan_socket), vxlan_socket_list) = LIST_HEAD_INITIALIZER(vxlan_socket_list); +#define V_vxlan_socket_list VNET(vxlan_socket_list) static eventhandler_tag vxlan_ifdetach_event_tag; @@ -428,12 +434,15 @@ SYSCTL_NODE(_net_link, OID_AUTO, vxlan, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Virtual eXtensible Local Area Network"); -static int vxlan_legacy_port = 0; -SYSCTL_INT(_net_link_vxlan, OID_AUTO, legacy_port, CTLFLAG_RWTUN, - &vxlan_legacy_port, 0, "Use legacy port"); -static int vxlan_reuse_port = 0; -SYSCTL_INT(_net_link_vxlan, OID_AUTO, reuse_port, CTLFLAG_RWTUN, - &vxlan_reuse_port, 0, "Re-use port"); +VNET_DEFINE_STATIC(int, vxlan_legacy_port) = 0; +#define V_vxlan_legacy_port VNET(vxlan_legacy_port) +SYSCTL_INT(_net_link_vxlan, OID_AUTO, legacy_port, CTLFLAG_VNET | CTLFLAG_RWTUN, + &VNET_NAME(vxlan_legacy_port), 0, "Use legacy port"); + +VNET_DEFINE_STATIC(int, vxlan_reuse_port) = 0; +#define V_vxlan_reuse_port VNET(vxlan_reuse_port) +SYSCTL_INT(_net_link_vxlan, OID_AUTO, reuse_port, CTLFLAG_VNET | CTLFLAG_RWTUN, + &VNET_NAME(vxlan_reuse_port), 0, "Re-use port"); /* * This macro controls the default upper limitation on nesting of vxlan @@ -446,9 +455,10 @@ #ifndef MAX_VXLAN_NEST #define MAX_VXLAN_NEST 3 #endif -static int max_vxlan_nesting = MAX_VXLAN_NEST; -SYSCTL_INT(_net_link_vxlan, OID_AUTO, max_nesting, CTLFLAG_RW, - &max_vxlan_nesting, 0, "Max nested tunnels"); +VNET_DEFINE_STATIC(int, max_vxlan_nesting) = MAX_VXLAN_NEST; +#define V_max_vxlan_nesting VNET(max_vxlan_nesting) +SYSCTL_INT(_net_link_vxlan, OID_AUTO, max_nesting, CTLFLAG_VNET | CTLFLAG_RW, + &VNET_NAME(max_vxlan_nesting), 0, "Max nested tunnels"); /* Default maximum number of addresses in the forwarding table. */ #ifndef VXLAN_FTABLE_MAX @@ -962,7 +972,7 @@ struct vxlan_socket *vso; VXLAN_LIST_LOCK(); - LIST_FOREACH(vso, &vxlan_socket_list, vxlso_entry) { + LIST_FOREACH(vso, &V_vxlan_socket_list, vxlso_entry) { if (vxlan_sockaddr_cmp(&vso->vxlso_laddr, &vxlsa->sa) == 0) { VXLAN_SO_ACQUIRE(vso); break; @@ -979,7 +989,7 @@ VXLAN_LIST_LOCK(); VXLAN_SO_ACQUIRE(vso); - LIST_INSERT_HEAD(&vxlan_socket_list, vso, vxlso_entry); + LIST_INSERT_HEAD(&V_vxlan_socket_list, vso, vxlso_entry); VXLAN_LIST_UNLOCK(); } @@ -1005,7 +1015,7 @@ return (error); } - if (vxlan_reuse_port != 0) { + if (V_vxlan_reuse_port != 0) { struct sockopt sopt; int val = 1; @@ -1907,7 +1917,9 @@ VXLAN_LOCK_WASSERT(sc); vxlan_ftable_expire(sc); + CURVNET_SET(sc->vxl_ifp->if_vnet); callout_schedule(&sc->vxl_callout, vxlan_ftable_prune_period * hz); + CURVNET_RESTORE(); } static int @@ -2770,7 +2782,7 @@ return (ENETDOWN); } if (__predict_false(if_tunnel_check_nesting(ifp, m, MTAG_VXLAN_LOOP, - max_vxlan_nesting) != 0)) { + V_max_vxlan_nesting) != 0)) { VXLAN_RUNLOCK(sc, &tracker); m_freem(m); if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); @@ -2959,7 +2971,9 @@ sc->vxl_vni = VXLAN_VNI_MAX; sc->vxl_ttl = IPDEFTTL; - if (!vxlan_tunable_int(sc, "legacy_port", vxlan_legacy_port)) { + memset(&sc->vxl_src_addr, 0, sizeof(sc->vxl_src_addr)); + memset(&sc->vxl_dst_addr, 0, sizeof(sc->vxl_src_addr)); + if (!vxlan_tunable_int(sc, "legacy_port", V_vxlan_legacy_port)) { sc->vxl_src_addr.in4.sin_port = htons(VXLAN_PORT); sc->vxl_dst_addr.in4.sin_port = htons(VXLAN_PORT); } else { @@ -3259,6 +3273,10 @@ ether_ifattach(ifp, sc->vxl_hwaddr.octet); ifp->if_baudrate = 0; +#ifdef VIMAGE + /* Override reassign function set by ether_ifattach() */ + ifp->if_reassign = vxlan_reassign; +#endif VXLAN_WLOCK(sc); vxlan_setup_interface_hdrlen(sc); @@ -3272,6 +3290,22 @@ return (error); } +#ifdef VIMAGE +static void +vxlan_reassign(struct ifnet *ifp, struct vnet *newvnet, char *arg) +{ + struct vxlan_softc *sc; + + sc = ifp->if_softc; + vxlan_teardown(sc); + ether_reassign(ifp, newvnet, arg); + + CURVNET_SET(newvnet); + vxlan_set_default_config(sc); + CURVNET_RESTORE(); +} +#endif /* VIMAGE */ + static int vxlan_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags) { @@ -3622,7 +3656,7 @@ return; VXLAN_LIST_LOCK(); - LIST_FOREACH(vso, &vxlan_socket_list, vxlso_entry) + LIST_FOREACH(vso, &V_vxlan_socket_list, vxlso_entry) vxlan_socket_ifdetach(vso, ifp, &list); VXLAN_LIST_UNLOCK(); @@ -3639,31 +3673,37 @@ } static void -vxlan_load(void) +vnet_vxlan_init(const void *dummy __unused) { - - mtx_init(&vxlan_list_mtx, "vxlan list", NULL, MTX_DEF); - vxlan_ifdetach_event_tag = EVENTHANDLER_REGISTER(ifnet_departure_event, - vxlan_ifdetach_event, NULL, EVENTHANDLER_PRI_ANY); + mtx_init(&V_vxlan_list_mtx, "vxlan list", NULL, MTX_DEF); struct if_clone_addreq req = { .create_f = vxlan_clone_create, .destroy_f = vxlan_clone_destroy, .flags = IFC_F_AUTOUNIT, }; - vxlan_cloner = ifc_attach_cloner(vxlan_name, &req); + V_vxlan_cloner = ifc_attach_cloner(vxlan_name, &req); } +VNET_SYSINIT(vnet_vxlan_init, SI_SUB_PSEUDO, SI_ORDER_ANY, + vnet_vxlan_init, NULL); static void -vxlan_unload(void) +vnet_vxlan_uninit(const void *dummy __unused) { + ifc_detach_cloner(V_vxlan_cloner); +} +VNET_SYSUNINIT(vnet_vxlan_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY, + vnet_vxlan_uninit, NULL); - EVENTHANDLER_DEREGISTER(ifnet_departure_event, - vxlan_ifdetach_event_tag); - ifc_detach_cloner(vxlan_cloner); - mtx_destroy(&vxlan_list_mtx); - MPASS(LIST_EMPTY(&vxlan_socket_list)); +static void +vnet_vxlan_mtx_uninit(const void *dummy __unused) +{ + MPASS(LIST_EMPTY(&V_vxlan_socket_list)); + /* ifnet_departure_event may want this, delay destroying */ + mtx_destroy(&V_vxlan_list_mtx); } +VNET_SYSUNINIT(vnet_vxlan_mtx_uninit, SI_SUB_INIT_IF - 1, SI_ORDER_ANY, + vnet_vxlan_mtx_uninit, NULL); static int vxlan_modevent(module_t mod, int type, void *unused) @@ -3674,10 +3714,13 @@ switch (type) { case MOD_LOAD: - vxlan_load(); + vxlan_ifdetach_event_tag = EVENTHANDLER_REGISTER( + ifnet_departure_event, vxlan_ifdetach_event, NULL, + EVENTHANDLER_PRI_ANY); break; case MOD_UNLOAD: - vxlan_unload(); + EVENTHANDLER_DEREGISTER(ifnet_departure_event, + vxlan_ifdetach_event_tag); break; default: error = ENOTSUP;