Changeset View
Changeset View
Standalone View
Standalone View
sys/net/if_vxlan.c
Show First 20 Lines • Show All 165 Lines • ▼ Show 20 Lines | struct vxlan_softc { | ||||
struct vxlan_socket *vxl_sock; | struct vxlan_socket *vxl_sock; | ||||
uint32_t vxl_vni; | uint32_t vxl_vni; | ||||
union vxlan_sockaddr vxl_src_addr; | union vxlan_sockaddr vxl_src_addr; | ||||
union vxlan_sockaddr vxl_dst_addr; | union vxlan_sockaddr vxl_dst_addr; | ||||
uint32_t vxl_flags; | uint32_t vxl_flags; | ||||
#define VXLAN_FLAG_INIT 0x0001 | #define VXLAN_FLAG_INIT 0x0001 | ||||
#define VXLAN_FLAG_TEARDOWN 0x0002 | #define VXLAN_FLAG_TEARDOWN 0x0002 | ||||
#define VXLAN_FLAG_LEARN 0x0004 | #define VXLAN_FLAG_LEARN 0x0004 | ||||
#define VXLAN_FLAG_USER_MTU 0x0008 | |||||
uint32_t vxl_port_hash_key; | uint32_t vxl_port_hash_key; | ||||
uint16_t vxl_min_port; | uint16_t vxl_min_port; | ||||
uint16_t vxl_max_port; | uint16_t vxl_max_port; | ||||
uint8_t vxl_ttl; | uint8_t vxl_ttl; | ||||
/* Lookup table from MAC address to forwarding entry. */ | /* Lookup table from MAC address to forwarding entry. */ | ||||
uint32_t vxl_ftable_cnt; | uint32_t vxl_ftable_cnt; | ||||
▲ Show 20 Lines • Show All 1,433 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
#endif | #endif | ||||
static void | static void | ||||
vxlan_setup_interface_hdrlen(struct vxlan_softc *sc) | vxlan_setup_interface_hdrlen(struct vxlan_softc *sc) | ||||
{ | { | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
VXLAN_LOCK_WASSERT(sc); | |||||
ifp = sc->vxl_ifp; | ifp = sc->vxl_ifp; | ||||
ifp->if_hdrlen = ETHER_HDR_LEN + sizeof(struct vxlanudphdr); | ifp->if_hdrlen = ETHER_HDR_LEN + sizeof(struct vxlanudphdr); | ||||
if (VXLAN_SOCKADDR_IS_IPV4(&sc->vxl_dst_addr) != 0) | if (VXLAN_SOCKADDR_IS_IPV4(&sc->vxl_dst_addr) != 0) | ||||
ifp->if_hdrlen += sizeof(struct ip); | ifp->if_hdrlen += sizeof(struct ip); | ||||
else if (VXLAN_SOCKADDR_IS_IPV6(&sc->vxl_dst_addr) != 0) | else if (VXLAN_SOCKADDR_IS_IPV6(&sc->vxl_dst_addr) != 0) | ||||
ifp->if_hdrlen += sizeof(struct ip6_hdr); | ifp->if_hdrlen += sizeof(struct ip6_hdr); | ||||
if ((sc->vxl_flags & VXLAN_FLAG_USER_MTU) == 0) | |||||
ifp->if_mtu = ETHERMTU - ifp->if_hdrlen; | |||||
} | } | ||||
static int | static int | ||||
vxlan_valid_init_config(struct vxlan_softc *sc) | vxlan_valid_init_config(struct vxlan_softc *sc) | ||||
{ | { | ||||
const char *reason; | const char *reason; | ||||
if (vxlan_check_vni(sc->vxl_vni) != 0) { | if (vxlan_check_vni(sc->vxl_vni) != 0) { | ||||
▲ Show 20 Lines • Show All 711 Lines • ▼ Show 20 Lines | case SIOCSIFFLAGS: | ||||
break; | break; | ||||
case SIOCSIFMEDIA: | case SIOCSIFMEDIA: | ||||
case SIOCGIFMEDIA: | case SIOCGIFMEDIA: | ||||
error = ifmedia_ioctl(ifp, ifr, &sc->vxl_media, cmd); | error = ifmedia_ioctl(ifp, ifr, &sc->vxl_media, cmd); | ||||
break; | break; | ||||
case SIOCSIFMTU: | case SIOCSIFMTU: | ||||
if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > VXLAN_MAX_MTU) | if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > VXLAN_MAX_MTU) { | ||||
error = EINVAL; | error = EINVAL; | ||||
else | } else { | ||||
VXLAN_WLOCK(sc); | |||||
ifp->if_mtu = ifr->ifr_mtu; | ifp->if_mtu = ifr->ifr_mtu; | ||||
sc->vxl_flags |= VXLAN_FLAG_USER_MTU; | |||||
VXLAN_WUNLOCK(sc); | |||||
} | |||||
break; | break; | ||||
case SIOCSIFCAP: | case SIOCSIFCAP: | ||||
VXLAN_WLOCK(sc); | VXLAN_WLOCK(sc); | ||||
error = vxlan_set_reqcap(sc, ifp, ifr->ifr_reqcap); | error = vxlan_set_reqcap(sc, ifp, ifr->ifr_reqcap); | ||||
if (error == 0) | if (error == 0) | ||||
vxlan_set_hwcaps(sc); | vxlan_set_hwcaps(sc); | ||||
VXLAN_WUNLOCK(sc); | VXLAN_WUNLOCK(sc); | ||||
▲ Show 20 Lines • Show All 837 Lines • ▼ Show 20 Lines | vxlan_clone_create(struct if_clone *ifc, int unit, caddr_t params) | ||||
ifmedia_init(&sc->vxl_media, 0, vxlan_media_change, vxlan_media_status); | ifmedia_init(&sc->vxl_media, 0, vxlan_media_change, vxlan_media_status); | ||||
ifmedia_add(&sc->vxl_media, IFM_ETHER | IFM_AUTO, 0, NULL); | ifmedia_add(&sc->vxl_media, IFM_ETHER | IFM_AUTO, 0, NULL); | ||||
ifmedia_set(&sc->vxl_media, IFM_ETHER | IFM_AUTO); | ifmedia_set(&sc->vxl_media, IFM_ETHER | IFM_AUTO); | ||||
ether_gen_addr(ifp, &sc->vxl_hwaddr); | ether_gen_addr(ifp, &sc->vxl_hwaddr); | ||||
ether_ifattach(ifp, sc->vxl_hwaddr.octet); | ether_ifattach(ifp, sc->vxl_hwaddr.octet); | ||||
ifp->if_baudrate = 0; | ifp->if_baudrate = 0; | ||||
VXLAN_WLOCK(sc); | |||||
kib: Note that at this point ifp is externally visible already. Doing vxlan_setup_interface_hdrlen… | |||||
vxlan_setup_interface_hdrlen(sc); | vxlan_setup_interface_hdrlen(sc); | ||||
VXLAN_WUNLOCK(sc); | |||||
return (0); | return (0); | ||||
fail: | fail: | ||||
free(sc, M_VXLAN); | free(sc, M_VXLAN); | ||||
return (error); | return (error); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 419 Lines • Show Last 20 Lines |
Note that at this point ifp is externally visible already. Doing vxlan_setup_interface_hdrlen() there without the lock is simply unsafe since other thread might start modifying this vxlan parameters.