Changeset View
Changeset View
Standalone View
Standalone View
sys/net/if_vxlan.c
Show First 20 Lines • Show All 157 Lines • ▼ Show 20 Lines | struct vxlan_statistics { | |||||||||||||
counter_u64_t txcsum; | counter_u64_t txcsum; | |||||||||||||
counter_u64_t tso; | counter_u64_t tso; | |||||||||||||
counter_u64_t rxcsum; | counter_u64_t rxcsum; | |||||||||||||
}; | }; | |||||||||||||
struct vxlan_softc { | struct vxlan_softc { | |||||||||||||
struct ifnet *vxl_ifp; | struct ifnet *vxl_ifp; | |||||||||||||
int vxl_reqcap; | int vxl_reqcap; | |||||||||||||
u_int vxl_fibnum; | ||||||||||||||
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 | |||||||||||||
▲ Show 20 Lines • Show All 2,199 Lines • ▼ Show 20 Lines | vxlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) | |||||||||||||
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); | |||||||||||||
break; | break; | |||||||||||||
case SIOCGTUNFIB: | ||||||||||||||
ifr->ifr_fib = sc->vxl_fibnum; | ||||||||||||||
bryanv: error is already initialized before the switch | ||||||||||||||
melifaroUnsubmitted Done Inline ActionsFor consistency I'd rather do a read lock here. melifaro: For consistency I'd rather do a read lock here. | ||||||||||||||
zleiAuthorUnsubmitted Done Inline Actions
Perfect! zlei: > For consistency I'd rather do a read lock here.
Perfect! | ||||||||||||||
break; | ||||||||||||||
case SIOCSTUNFIB: | ||||||||||||||
if ((error = priv_check(curthread, PRIV_NET_VXLAN)) != 0) | ||||||||||||||
break; | ||||||||||||||
if (ifr->ifr_fib >= rt_numfibs) | ||||||||||||||
error = EINVAL; | ||||||||||||||
else { | ||||||||||||||
VXLAN_WLOCK(sc); | ||||||||||||||
sc->vxl_fibnum = ifr->ifr_fib; | ||||||||||||||
VXLAN_WUNLOCK(sc); | ||||||||||||||
} | ||||||||||||||
break; | ||||||||||||||
default: | default: | |||||||||||||
error = ether_ioctl(ifp, cmd, data); | error = ether_ioctl(ifp, cmd, data); | |||||||||||||
break; | break; | |||||||||||||
} | } | |||||||||||||
return (error); | return (error); | |||||||||||||
} | } | |||||||||||||
▲ Show 20 Lines • Show All 139 Lines • ▼ Show 20 Lines | if (m->m_pkthdr.csum_flags != 0) { | |||||||||||||
* inner frame. | * inner frame. | |||||||||||||
*/ | */ | |||||||||||||
bzero(&route, sizeof(route)); | bzero(&route, sizeof(route)); | |||||||||||||
ro = &route; | ro = &route; | |||||||||||||
sin = (struct sockaddr_in *)&ro->ro_dst; | sin = (struct sockaddr_in *)&ro->ro_dst; | |||||||||||||
sin->sin_family = AF_INET; | sin->sin_family = AF_INET; | |||||||||||||
sin->sin_len = sizeof(*sin); | sin->sin_len = sizeof(*sin); | |||||||||||||
sin->sin_addr = ip->ip_dst; | sin->sin_addr = ip->ip_dst; | |||||||||||||
ro->ro_nh = fib4_lookup(RT_DEFAULT_FIB, ip->ip_dst, 0, NHR_NONE, | ro->ro_nh = fib4_lookup(M_GETFIB(m), ip->ip_dst, 0, NHR_NONE, | |||||||||||||
0); | 0); | |||||||||||||
if (ro->ro_nh == NULL) { | if (ro->ro_nh == NULL) { | |||||||||||||
m_freem(m); | m_freem(m); | |||||||||||||
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | |||||||||||||
return (EHOSTUNREACH); | return (EHOSTUNREACH); | |||||||||||||
} | } | |||||||||||||
csum_flags = csum_flags_to_inner_flags(m->m_pkthdr.csum_flags, | csum_flags = csum_flags_to_inner_flags(m->m_pkthdr.csum_flags, | |||||||||||||
▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | if (m->m_pkthdr.csum_flags != 0) { | |||||||||||||
* inner frame. | * inner frame. | |||||||||||||
*/ | */ | |||||||||||||
bzero(&route, sizeof(route)); | bzero(&route, sizeof(route)); | |||||||||||||
ro = &route; | ro = &route; | |||||||||||||
sin6 = (struct sockaddr_in6 *)&ro->ro_dst; | sin6 = (struct sockaddr_in6 *)&ro->ro_dst; | |||||||||||||
sin6->sin6_family = AF_INET6; | sin6->sin6_family = AF_INET6; | |||||||||||||
sin6->sin6_len = sizeof(*sin6); | sin6->sin6_len = sizeof(*sin6); | |||||||||||||
sin6->sin6_addr = ip6->ip6_dst; | sin6->sin6_addr = ip6->ip6_dst; | |||||||||||||
ro->ro_nh = fib6_lookup(RT_DEFAULT_FIB, &ip6->ip6_dst, 0, | ro->ro_nh = fib6_lookup(M_GETFIB(m), &ip6->ip6_dst, 0, | |||||||||||||
NHR_NONE, 0); | NHR_NONE, 0); | |||||||||||||
if (ro->ro_nh == NULL) { | if (ro->ro_nh == NULL) { | |||||||||||||
m_freem(m); | m_freem(m); | |||||||||||||
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | |||||||||||||
return (EHOSTUNREACH); | return (EHOSTUNREACH); | |||||||||||||
} | } | |||||||||||||
csum_flags = csum_flags_to_inner_flags(m->m_pkthdr.csum_flags, | csum_flags = csum_flags_to_inner_flags(m->m_pkthdr.csum_flags, | |||||||||||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | vxlan_transmit(struct ifnet *ifp, struct mbuf *m) | |||||||||||||
struct ether_header *eh; | struct ether_header *eh; | |||||||||||||
int ipv4, error; | int ipv4, error; | |||||||||||||
sc = ifp->if_softc; | sc = ifp->if_softc; | |||||||||||||
eh = mtod(m, struct ether_header *); | eh = mtod(m, struct ether_header *); | |||||||||||||
fe = NULL; | fe = NULL; | |||||||||||||
mcifp = NULL; | mcifp = NULL; | |||||||||||||
M_SETFIB(m, sc->vxl_fibnum); | ||||||||||||||
ETHER_BPF_MTAP(ifp, m); | ETHER_BPF_MTAP(ifp, m); | |||||||||||||
VXLAN_RLOCK(sc, &tracker); | VXLAN_RLOCK(sc, &tracker); | |||||||||||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { | if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { | |||||||||||||
melifaroUnsubmitted Done Inline Actions
I'd rather move it down - so (1) it is protected by the lock and (2) it reflect the reality - we pass the packet to BPF for own transmit, not tunnelled transmit, so the packet should retain the fib. melifaro: I'd rather move it down - so (1) it is protected by the lock and (2) it reflect the reality… | ||||||||||||||
zleiAuthorUnsubmitted Done Inline ActionsSmart! zlei: Smart! | ||||||||||||||
VXLAN_RUNLOCK(sc, &tracker); | VXLAN_RUNLOCK(sc, &tracker); | |||||||||||||
m_freem(m); | m_freem(m); | |||||||||||||
return (ENETDOWN); | return (ENETDOWN); | |||||||||||||
} | } | |||||||||||||
if ((m->m_flags & (M_BCAST | M_MCAST)) == 0) | if ((m->m_flags & (M_BCAST | M_MCAST)) == 0) | |||||||||||||
fe = vxlan_ftable_entry_lookup(sc, eh->ether_dhost); | fe = vxlan_ftable_entry_lookup(sc, eh->ether_dhost); | |||||||||||||
if (fe == NULL) | if (fe == NULL) | |||||||||||||
fe = &sc->vxl_default_fe; | fe = &sc->vxl_default_fe; | |||||||||||||
vxlan_sockaddr_copy(&vxlsa, &fe->vxlfe_raddr.sa); | vxlan_sockaddr_copy(&vxlsa, &fe->vxlfe_raddr.sa); | |||||||||||||
ipv4 = VXLAN_SOCKADDR_IS_IPV4(&vxlsa) != 0; | ipv4 = VXLAN_SOCKADDR_IS_IPV4(&vxlsa) != 0; | |||||||||||||
if (vxlan_sockaddr_in_multicast(&vxlsa) != 0) | if (vxlan_sockaddr_in_multicast(&vxlsa) != 0) | |||||||||||||
mcifp = vxlan_multicast_if_ref(sc, ipv4); | mcifp = vxlan_multicast_if_ref(sc, ipv4); | |||||||||||||
VXLAN_ACQUIRE(sc); | VXLAN_ACQUIRE(sc); | |||||||||||||
Done Inline ActionsThe softc lock isn't held for this in the ioctl handler - which is probably fine, or at least other tunnelers have the same race - so I don't think this needs to be under the lock. bryanv: The softc lock isn't held for this in the ioctl handler - which is probably fine, or at least… | ||||||||||||||
VXLAN_RUNLOCK(sc, &tracker); | VXLAN_RUNLOCK(sc, &tracker); | |||||||||||||
if (ipv4 != 0) | if (ipv4 != 0) | |||||||||||||
error = vxlan_encap4(sc, &vxlsa, m); | error = vxlan_encap4(sc, &vxlsa, m); | |||||||||||||
else | else | |||||||||||||
error = vxlan_encap6(sc, &vxlsa, m); | error = vxlan_encap6(sc, &vxlsa, m); | |||||||||||||
vxlan_release(sc); | vxlan_release(sc); | |||||||||||||
▲ Show 20 Lines • Show All 426 Lines • ▼ Show 20 Lines | ||||||||||||||
{ | { | |||||||||||||
struct vxlan_softc *sc; | struct vxlan_softc *sc; | |||||||||||||
struct ifnet *ifp; | struct ifnet *ifp; | |||||||||||||
struct ifvxlanparam vxlp; | struct ifvxlanparam vxlp; | |||||||||||||
int error; | int error; | |||||||||||||
sc = malloc(sizeof(struct vxlan_softc), M_VXLAN, M_WAITOK | M_ZERO); | sc = malloc(sizeof(struct vxlan_softc), M_VXLAN, M_WAITOK | M_ZERO); | |||||||||||||
sc->vxl_unit = unit; | sc->vxl_unit = unit; | |||||||||||||
sc->vxl_fibnum = curthread->td_proc->p_fibnum; | ||||||||||||||
vxlan_set_default_config(sc); | vxlan_set_default_config(sc); | |||||||||||||
error = vxlan_stats_alloc(sc); | error = vxlan_stats_alloc(sc); | |||||||||||||
if (error != 0) | if (error != 0) | |||||||||||||
goto fail; | goto fail; | |||||||||||||
if (params != 0) { | if (params != 0) { | |||||||||||||
error = copyin(params, &vxlp, sizeof(vxlp)); | error = copyin(params, &vxlp, sizeof(vxlp)); | |||||||||||||
if (error) | if (error) | |||||||||||||
▲ Show 20 Lines • Show All 472 Lines • Show Last 20 Lines |
error is already initialized before the switch