if_vxlan.c (0e253fd12cb8db29ec3c3aeef5d6b2345fa6f5c7) if_vxlan.c (33e0d8f057cf6eda187f09c76ea968c19e176b74)
1/*-
2 * Copyright (c) 2014, Bryan Venteicher <bryanv@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 54 unchanged lines hidden (view full) ---

63
64#include <netinet/in.h>
65#include <netinet/in_systm.h>
66#include <netinet/in_var.h>
67#include <netinet/in_pcb.h>
68#include <netinet/ip.h>
69#include <netinet/ip6.h>
70#include <netinet/ip_var.h>
1/*-
2 * Copyright (c) 2014, Bryan Venteicher <bryanv@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 54 unchanged lines hidden (view full) ---

63
64#include <netinet/in.h>
65#include <netinet/in_systm.h>
66#include <netinet/in_var.h>
67#include <netinet/in_pcb.h>
68#include <netinet/ip.h>
69#include <netinet/ip6.h>
70#include <netinet/ip_var.h>
71#include <netinet6/ip6_var.h>
72#include <netinet/udp.h>
73#include <netinet/udp_var.h>
74
71#include <netinet/udp.h>
72#include <netinet/udp_var.h>
73
74#include <netinet6/ip6_var.h>
75#include <netinet6/scope6_var.h>
76
75struct vxlan_softc;
76LIST_HEAD(vxlan_softc_head, vxlan_softc);
77
78struct vxlan_socket_mc_info {
79 union vxlan_sockaddr vxlsomc_saddr;
80 union vxlan_sockaddr vxlsomc_gaddr;
81 int vxlsomc_ifidx;
82 int vxlsomc_users;

--- 127 unchanged lines hidden (view full) ---

210} __packed;
211
212static int vxlan_ftable_addr_cmp(const uint8_t *, const uint8_t *);
213static void vxlan_ftable_init(struct vxlan_softc *);
214static void vxlan_ftable_fini(struct vxlan_softc *);
215static void vxlan_ftable_flush(struct vxlan_softc *, int);
216static void vxlan_ftable_expire(struct vxlan_softc *);
217static int vxlan_ftable_update_locked(struct vxlan_softc *,
77struct vxlan_softc;
78LIST_HEAD(vxlan_softc_head, vxlan_softc);
79
80struct vxlan_socket_mc_info {
81 union vxlan_sockaddr vxlsomc_saddr;
82 union vxlan_sockaddr vxlsomc_gaddr;
83 int vxlsomc_ifidx;
84 int vxlsomc_users;

--- 127 unchanged lines hidden (view full) ---

212} __packed;
213
214static int vxlan_ftable_addr_cmp(const uint8_t *, const uint8_t *);
215static void vxlan_ftable_init(struct vxlan_softc *);
216static void vxlan_ftable_fini(struct vxlan_softc *);
217static void vxlan_ftable_flush(struct vxlan_softc *, int);
218static void vxlan_ftable_expire(struct vxlan_softc *);
219static int vxlan_ftable_update_locked(struct vxlan_softc *,
218 const struct sockaddr *, const uint8_t *,
220 const union vxlan_sockaddr *, const uint8_t *,
219 struct rm_priotracker *);
221 struct rm_priotracker *);
220static int vxlan_ftable_update(struct vxlan_softc *,
222static int vxlan_ftable_learn(struct vxlan_softc *,
221 const struct sockaddr *, const uint8_t *);
222static int vxlan_ftable_sysctl_dump(SYSCTL_HANDLER_ARGS);
223
224static struct vxlan_ftable_entry *
225 vxlan_ftable_entry_alloc(void);
226static void vxlan_ftable_entry_free(struct vxlan_ftable_entry *);
227static void vxlan_ftable_entry_init(struct vxlan_softc *,
228 struct vxlan_ftable_entry *, const uint8_t *,

--- 124 unchanged lines hidden (view full) ---

353 const struct sockaddr *);
354static int vxlan_sockaddr_in_equal(const union vxlan_sockaddr *,
355 const struct sockaddr *);
356static void vxlan_sockaddr_in_copy(union vxlan_sockaddr *,
357 const struct sockaddr *);
358static int vxlan_sockaddr_supported(const union vxlan_sockaddr *, int);
359static int vxlan_sockaddr_in_any(const union vxlan_sockaddr *);
360static int vxlan_sockaddr_in_multicast(const union vxlan_sockaddr *);
223 const struct sockaddr *, const uint8_t *);
224static int vxlan_ftable_sysctl_dump(SYSCTL_HANDLER_ARGS);
225
226static struct vxlan_ftable_entry *
227 vxlan_ftable_entry_alloc(void);
228static void vxlan_ftable_entry_free(struct vxlan_ftable_entry *);
229static void vxlan_ftable_entry_init(struct vxlan_softc *,
230 struct vxlan_ftable_entry *, const uint8_t *,

--- 124 unchanged lines hidden (view full) ---

355 const struct sockaddr *);
356static int vxlan_sockaddr_in_equal(const union vxlan_sockaddr *,
357 const struct sockaddr *);
358static void vxlan_sockaddr_in_copy(union vxlan_sockaddr *,
359 const struct sockaddr *);
360static int vxlan_sockaddr_supported(const union vxlan_sockaddr *, int);
361static int vxlan_sockaddr_in_any(const union vxlan_sockaddr *);
362static int vxlan_sockaddr_in_multicast(const union vxlan_sockaddr *);
363static int vxlan_sockaddr_in6_embedscope(union vxlan_sockaddr *);
361
362static int vxlan_can_change_config(struct vxlan_softc *);
363static int vxlan_check_vni(uint32_t);
364static int vxlan_check_ttl(int);
365static int vxlan_check_ftable_timeout(uint32_t);
366static int vxlan_check_ftable_max(uint32_t);
367
368static void vxlan_sysctl_setup(struct vxlan_softc *);

--- 202 unchanged lines hidden (view full) ---

571 if (VXLAN_FE_IS_DYNAMIC(fe) &&
572 time_uptime >= fe->vxlfe_expire)
573 vxlan_ftable_entry_destroy(sc, fe);
574 }
575 }
576}
577
578static int
364
365static int vxlan_can_change_config(struct vxlan_softc *);
366static int vxlan_check_vni(uint32_t);
367static int vxlan_check_ttl(int);
368static int vxlan_check_ftable_timeout(uint32_t);
369static int vxlan_check_ftable_max(uint32_t);
370
371static void vxlan_sysctl_setup(struct vxlan_softc *);

--- 202 unchanged lines hidden (view full) ---

574 if (VXLAN_FE_IS_DYNAMIC(fe) &&
575 time_uptime >= fe->vxlfe_expire)
576 vxlan_ftable_entry_destroy(sc, fe);
577 }
578 }
579}
580
581static int
579vxlan_ftable_update_locked(struct vxlan_softc *sc, const struct sockaddr *sa,
580 const uint8_t *mac, struct rm_priotracker *tracker)
582vxlan_ftable_update_locked(struct vxlan_softc *sc,
583 const union vxlan_sockaddr *vxlsa, const uint8_t *mac,
584 struct rm_priotracker *tracker)
581{
585{
582 union vxlan_sockaddr vxlsa;
583 struct vxlan_ftable_entry *fe;
584 int error;
585
586 VXLAN_LOCK_ASSERT(sc);
587
588again:
589 /*
590 * A forwarding entry for this MAC address might already exist. If
591 * so, update it, otherwise create a new one. We may have to upgrade
592 * the lock if we have to change or create an entry.
593 */
594 fe = vxlan_ftable_entry_lookup(sc, mac);
595 if (fe != NULL) {
596 fe->vxlfe_expire = time_uptime + sc->vxl_ftable_timeout;
597
598 if (!VXLAN_FE_IS_DYNAMIC(fe) ||
586 struct vxlan_ftable_entry *fe;
587 int error;
588
589 VXLAN_LOCK_ASSERT(sc);
590
591again:
592 /*
593 * A forwarding entry for this MAC address might already exist. If
594 * so, update it, otherwise create a new one. We may have to upgrade
595 * the lock if we have to change or create an entry.
596 */
597 fe = vxlan_ftable_entry_lookup(sc, mac);
598 if (fe != NULL) {
599 fe->vxlfe_expire = time_uptime + sc->vxl_ftable_timeout;
600
601 if (!VXLAN_FE_IS_DYNAMIC(fe) ||
599 vxlan_sockaddr_in_equal(&fe->vxlfe_raddr, sa))
602 vxlan_sockaddr_in_equal(&fe->vxlfe_raddr, &vxlsa->sa))
600 return (0);
601 if (!VXLAN_LOCK_WOWNED(sc)) {
602 VXLAN_RUNLOCK(sc, tracker);
603 VXLAN_WLOCK(sc);
604 sc->vxl_stats.ftable_lock_upgrade_failed++;
605 goto again;
606 }
603 return (0);
604 if (!VXLAN_LOCK_WOWNED(sc)) {
605 VXLAN_RUNLOCK(sc, tracker);
606 VXLAN_WLOCK(sc);
607 sc->vxl_stats.ftable_lock_upgrade_failed++;
608 goto again;
609 }
607 vxlan_sockaddr_in_copy(&fe->vxlfe_raddr, sa);
610 vxlan_sockaddr_in_copy(&fe->vxlfe_raddr, &vxlsa->sa);
608 return (0);
609 }
610
611 if (!VXLAN_LOCK_WOWNED(sc)) {
612 VXLAN_RUNLOCK(sc, tracker);
613 VXLAN_WLOCK(sc);
614 sc->vxl_stats.ftable_lock_upgrade_failed++;
615 goto again;
616 }
617
618 if (sc->vxl_ftable_cnt >= sc->vxl_ftable_max) {
619 sc->vxl_stats.ftable_nospace++;
620 return (ENOSPC);
621 }
622
623 fe = vxlan_ftable_entry_alloc();
624 if (fe == NULL)
625 return (ENOMEM);
626
611 return (0);
612 }
613
614 if (!VXLAN_LOCK_WOWNED(sc)) {
615 VXLAN_RUNLOCK(sc, tracker);
616 VXLAN_WLOCK(sc);
617 sc->vxl_stats.ftable_lock_upgrade_failed++;
618 goto again;
619 }
620
621 if (sc->vxl_ftable_cnt >= sc->vxl_ftable_max) {
622 sc->vxl_stats.ftable_nospace++;
623 return (ENOSPC);
624 }
625
626 fe = vxlan_ftable_entry_alloc();
627 if (fe == NULL)
628 return (ENOMEM);
629
627 /*
628 * The source port may be randomly select by the remove host, so
629 * use the port of the default destination address.
630 */
631 vxlan_sockaddr_copy(&vxlsa, sa);
632 vxlsa.in4.sin_port = sc->vxl_dst_addr.in4.sin_port;
630 vxlan_ftable_entry_init(sc, fe, mac, &vxlsa->sa, VXLAN_FE_FLAG_DYNAMIC);
633
631
634 vxlan_ftable_entry_init(sc, fe, mac, &vxlsa.sa,
635 VXLAN_FE_FLAG_DYNAMIC);
636
637 /* The prior lookup failed, so the insert should not. */
638 error = vxlan_ftable_entry_insert(sc, fe);
639 MPASS(error == 0);
640
641 return (0);
642}
643
644static int
632 /* The prior lookup failed, so the insert should not. */
633 error = vxlan_ftable_entry_insert(sc, fe);
634 MPASS(error == 0);
635
636 return (0);
637}
638
639static int
645vxlan_ftable_update(struct vxlan_softc *sc, const struct sockaddr *sa,
640vxlan_ftable_learn(struct vxlan_softc *sc, const struct sockaddr *sa,
646 const uint8_t *mac)
647{
648 struct rm_priotracker tracker;
641 const uint8_t *mac)
642{
643 struct rm_priotracker tracker;
644 union vxlan_sockaddr vxlsa;
649 int error;
650
645 int error;
646
647 /*
648 * The source port may be randomly selected by the remote host, so
649 * use the port of the default destination address.
650 */
651 vxlan_sockaddr_copy(&vxlsa, sa);
652 vxlsa.in4.sin_port = sc->vxl_dst_addr.in4.sin_port;
653
654 if (VXLAN_SOCKADDR_IS_IPV6(&vxlsa)) {
655 error = vxlan_sockaddr_in6_embedscope(&vxlsa);
656 if (error)
657 return (error);
658 }
659
651 VXLAN_RLOCK(sc, &tracker);
660 VXLAN_RLOCK(sc, &tracker);
652 error = vxlan_ftable_update_locked(sc, sa, mac, &tracker);
661 error = vxlan_ftable_update_locked(sc, &vxlsa, mac, &tracker);
653 VXLAN_UNLOCK(sc, &tracker);
654
655 return (error);
656}
657
658static int
659vxlan_ftable_sysctl_dump(SYSCTL_HANDLER_ARGS)
660{

--- 385 unchanged lines hidden (view full) ---

1046 vxlan_ifdetach(sc, ifp, list);
1047 }
1048 VXLAN_SO_RUNLOCK(vso, &tracker);
1049}
1050
1051static struct vxlan_socket *
1052vxlan_socket_mc_lookup(const union vxlan_sockaddr *vxlsa)
1053{
662 VXLAN_UNLOCK(sc, &tracker);
663
664 return (error);
665}
666
667static int
668vxlan_ftable_sysctl_dump(SYSCTL_HANDLER_ARGS)
669{

--- 385 unchanged lines hidden (view full) ---

1055 vxlan_ifdetach(sc, ifp, list);
1056 }
1057 VXLAN_SO_RUNLOCK(vso, &tracker);
1058}
1059
1060static struct vxlan_socket *
1061vxlan_socket_mc_lookup(const union vxlan_sockaddr *vxlsa)
1062{
1054 struct vxlan_socket *vso;
1055 union vxlan_sockaddr laddr;
1063 union vxlan_sockaddr laddr;
1064 struct vxlan_socket *vso;
1056
1057 laddr = *vxlsa;
1058
1059 if (VXLAN_SOCKADDR_IS_IPV4(&laddr))
1060 laddr.in4.sin_addr.s_addr = INADDR_ANY;
1061#ifdef INET6
1062 else
1063 laddr.in6.sin6_addr = in6addr_any;

--- 337 unchanged lines hidden (view full) ---

1401
1402static int
1403vxlan_setup_multicast_interface(struct vxlan_softc *sc)
1404{
1405 struct ifnet *ifp;
1406
1407 ifp = ifunit_ref(sc->vxl_mc_ifname);
1408 if (ifp == NULL) {
1065
1066 laddr = *vxlsa;
1067
1068 if (VXLAN_SOCKADDR_IS_IPV4(&laddr))
1069 laddr.in4.sin_addr.s_addr = INADDR_ANY;
1070#ifdef INET6
1071 else
1072 laddr.in6.sin6_addr = in6addr_any;

--- 337 unchanged lines hidden (view full) ---

1410
1411static int
1412vxlan_setup_multicast_interface(struct vxlan_softc *sc)
1413{
1414 struct ifnet *ifp;
1415
1416 ifp = ifunit_ref(sc->vxl_mc_ifname);
1417 if (ifp == NULL) {
1409 if_printf(sc->vxl_ifp, "multicast interfaces %s does "
1418 if_printf(sc->vxl_ifp, "multicast interface %s does "
1410 "not exist\n", sc->vxl_mc_ifname);
1411 return (ENOENT);
1412 }
1413
1414 if ((ifp->if_flags & IFF_MULTICAST) == 0) {
1415 if_printf(sc->vxl_ifp, "interface %s does not support "
1416 "multicast\n", sc->vxl_mc_ifname);
1417 if_rele(ifp);

--- 407 unchanged lines hidden (view full) ---

1825 cfg->vxlc_ftable_max = sc->vxl_ftable_max;
1826 cfg->vxlc_ftable_timeout = sc->vxl_ftable_timeout;
1827 cfg->vxlc_port_min = sc->vxl_min_port;
1828 cfg->vxlc_port_max = sc->vxl_max_port;
1829 cfg->vxlc_learn = (sc->vxl_flags & VXLAN_FLAG_LEARN) != 0;
1830 cfg->vxlc_ttl = sc->vxl_ttl;
1831 VXLAN_RUNLOCK(sc, &tracker);
1832
1419 "not exist\n", sc->vxl_mc_ifname);
1420 return (ENOENT);
1421 }
1422
1423 if ((ifp->if_flags & IFF_MULTICAST) == 0) {
1424 if_printf(sc->vxl_ifp, "interface %s does not support "
1425 "multicast\n", sc->vxl_mc_ifname);
1426 if_rele(ifp);

--- 407 unchanged lines hidden (view full) ---

1834 cfg->vxlc_ftable_max = sc->vxl_ftable_max;
1835 cfg->vxlc_ftable_timeout = sc->vxl_ftable_timeout;
1836 cfg->vxlc_port_min = sc->vxl_min_port;
1837 cfg->vxlc_port_max = sc->vxl_max_port;
1838 cfg->vxlc_learn = (sc->vxl_flags & VXLAN_FLAG_LEARN) != 0;
1839 cfg->vxlc_ttl = sc->vxl_ttl;
1840 VXLAN_RUNLOCK(sc, &tracker);
1841
1842#ifdef INET6
1843 if (VXLAN_SOCKADDR_IS_IPV6(&cfg->vxlc_local_sa))
1844 sa6_recoverscope(&cfg->vxlc_local_sa.in6);
1845 if (VXLAN_SOCKADDR_IS_IPV6(&cfg->vxlc_remote_sa))
1846 sa6_recoverscope(&cfg->vxlc_remote_sa.in6);
1847#endif
1848
1833 return (0);
1834}
1835
1836static int
1837vxlan_ctrl_set_vni(struct vxlan_softc *sc, void *arg)
1838{
1839 struct ifvxlancmd *cmd;
1840 int error;

--- 23 unchanged lines hidden (view full) ---

1864
1865 cmd = arg;
1866 vxlsa = &cmd->vxlcmd_sa;
1867
1868 if (!VXLAN_SOCKADDR_IS_IPV46(vxlsa))
1869 return (EINVAL);
1870 if (vxlan_sockaddr_in_multicast(vxlsa) != 0)
1871 return (EINVAL);
1849 return (0);
1850}
1851
1852static int
1853vxlan_ctrl_set_vni(struct vxlan_softc *sc, void *arg)
1854{
1855 struct ifvxlancmd *cmd;
1856 int error;

--- 23 unchanged lines hidden (view full) ---

1880
1881 cmd = arg;
1882 vxlsa = &cmd->vxlcmd_sa;
1883
1884 if (!VXLAN_SOCKADDR_IS_IPV46(vxlsa))
1885 return (EINVAL);
1886 if (vxlan_sockaddr_in_multicast(vxlsa) != 0)
1887 return (EINVAL);
1888 if (VXLAN_SOCKADDR_IS_IPV6(vxlsa)) {
1889 error = vxlan_sockaddr_in6_embedscope(vxlsa);
1890 if (error)
1891 return (error);
1892 }
1872
1873 VXLAN_WLOCK(sc);
1874 if (vxlan_can_change_config(sc)) {
1875 vxlan_sockaddr_in_copy(&sc->vxl_src_addr, &vxlsa->sa);
1876 error = 0;
1877 } else
1878 error = EBUSY;
1879 VXLAN_WUNLOCK(sc);

--- 8 unchanged lines hidden (view full) ---

1888 union vxlan_sockaddr *vxlsa;
1889 int error;
1890
1891 cmd = arg;
1892 vxlsa = &cmd->vxlcmd_sa;
1893
1894 if (!VXLAN_SOCKADDR_IS_IPV46(vxlsa))
1895 return (EINVAL);
1893
1894 VXLAN_WLOCK(sc);
1895 if (vxlan_can_change_config(sc)) {
1896 vxlan_sockaddr_in_copy(&sc->vxl_src_addr, &vxlsa->sa);
1897 error = 0;
1898 } else
1899 error = EBUSY;
1900 VXLAN_WUNLOCK(sc);

--- 8 unchanged lines hidden (view full) ---

1909 union vxlan_sockaddr *vxlsa;
1910 int error;
1911
1912 cmd = arg;
1913 vxlsa = &cmd->vxlcmd_sa;
1914
1915 if (!VXLAN_SOCKADDR_IS_IPV46(vxlsa))
1916 return (EINVAL);
1917 if (VXLAN_SOCKADDR_IS_IPV6(vxlsa)) {
1918 error = vxlan_sockaddr_in6_embedscope(vxlsa);
1919 if (error)
1920 return (error);
1921 }
1896
1897 VXLAN_WLOCK(sc);
1898 if (vxlan_can_change_config(sc)) {
1899 vxlan_sockaddr_in_copy(&sc->vxl_dst_addr, &vxlsa->sa);
1900 error = 0;
1901 } else
1902 error = EBUSY;
1903 VXLAN_WUNLOCK(sc);

--- 184 unchanged lines hidden (view full) ---

2088 if (vxlan_sockaddr_in_any(&vxlsa) != 0)
2089 return (EINVAL);
2090 if (vxlan_sockaddr_in_multicast(&vxlsa) != 0)
2091 return (EINVAL);
2092 /* BMV: We could support both IPv4 and IPv6 later. */
2093 if (vxlsa.sa.sa_family != sc->vxl_dst_addr.sa.sa_family)
2094 return (EAFNOSUPPORT);
2095
1922
1923 VXLAN_WLOCK(sc);
1924 if (vxlan_can_change_config(sc)) {
1925 vxlan_sockaddr_in_copy(&sc->vxl_dst_addr, &vxlsa->sa);
1926 error = 0;
1927 } else
1928 error = EBUSY;
1929 VXLAN_WUNLOCK(sc);

--- 184 unchanged lines hidden (view full) ---

2114 if (vxlan_sockaddr_in_any(&vxlsa) != 0)
2115 return (EINVAL);
2116 if (vxlan_sockaddr_in_multicast(&vxlsa) != 0)
2117 return (EINVAL);
2118 /* BMV: We could support both IPv4 and IPv6 later. */
2119 if (vxlsa.sa.sa_family != sc->vxl_dst_addr.sa.sa_family)
2120 return (EAFNOSUPPORT);
2121
2122 if (VXLAN_SOCKADDR_IS_IPV6(&vxlsa)) {
2123 error = vxlan_sockaddr_in6_embedscope(&vxlsa);
2124 if (error)
2125 return (error);
2126 }
2127
2096 fe = vxlan_ftable_entry_alloc();
2097 if (fe == NULL)
2098 return (ENOMEM);
2099
2100 if (vxlsa.in4.sin_port == 0)
2101 vxlsa.in4.sin_port = sc->vxl_dst_addr.in4.sin_port;
2102
2103 vxlan_ftable_entry_init(sc, fe, cmd->vxlcmd_mac, &vxlsa.sa,

--- 139 unchanged lines hidden (view full) ---

2243static uint16_t
2244vxlan_pick_source_port(struct vxlan_softc *sc, struct mbuf *m)
2245{
2246 int range;
2247 uint32_t hash;
2248
2249 range = sc->vxl_max_port - sc->vxl_min_port + 1;
2250
2128 fe = vxlan_ftable_entry_alloc();
2129 if (fe == NULL)
2130 return (ENOMEM);
2131
2132 if (vxlsa.in4.sin_port == 0)
2133 vxlsa.in4.sin_port = sc->vxl_dst_addr.in4.sin_port;
2134
2135 vxlan_ftable_entry_init(sc, fe, cmd->vxlcmd_mac, &vxlsa.sa,

--- 139 unchanged lines hidden (view full) ---

2275static uint16_t
2276vxlan_pick_source_port(struct vxlan_softc *sc, struct mbuf *m)
2277{
2278 int range;
2279 uint32_t hash;
2280
2281 range = sc->vxl_max_port - sc->vxl_min_port + 1;
2282
2251 /* check if flowid is set and not opaque */
2252 if (M_HASHTYPE_ISHASH(m))
2253 hash = m->m_pkthdr.flowid;
2254 else
2255 hash = jenkins_hash(m->m_data, ETHER_HDR_LEN,
2256 sc->vxl_port_hash_key);
2257
2258 return (sc->vxl_min_port + (hash % range));
2259}

--- 271 unchanged lines hidden (view full) ---

2531 goto out;
2532 } else if (ifp == m->m_pkthdr.rcvif) {
2533 /* XXX Does not catch more complex loops. */
2534 error = EDEADLK;
2535 goto out;
2536 }
2537
2538 if (sc->vxl_flags & VXLAN_FLAG_LEARN)
2283 if (M_HASHTYPE_ISHASH(m))
2284 hash = m->m_pkthdr.flowid;
2285 else
2286 hash = jenkins_hash(m->m_data, ETHER_HDR_LEN,
2287 sc->vxl_port_hash_key);
2288
2289 return (sc->vxl_min_port + (hash % range));
2290}

--- 271 unchanged lines hidden (view full) ---

2562 goto out;
2563 } else if (ifp == m->m_pkthdr.rcvif) {
2564 /* XXX Does not catch more complex loops. */
2565 error = EDEADLK;
2566 goto out;
2567 }
2568
2569 if (sc->vxl_flags & VXLAN_FLAG_LEARN)
2539 vxlan_ftable_update(sc, sa, eh->ether_shost);
2570 vxlan_ftable_learn(sc, sa, eh->ether_shost);
2540
2541 m_clrprotoflags(m);
2542 m->m_pkthdr.rcvif = ifp;
2543 M_SETFIB(m, ifp->if_fib);
2544
2545 error = netisr_queue_src(NETISR_ETHER, 0, m);
2546 *m0 = NULL;
2547

--- 35 unchanged lines hidden (view full) ---

2583 VXLAN_PARAM_WITH_REMOTE_ADDR4))
2584 return (EAFNOSUPPORT);
2585#endif
2586
2587#ifndef INET6
2588 if (vxlp->vxlp_with & (VXLAN_PARAM_WITH_LOCAL_ADDR6 |
2589 VXLAN_PARAM_WITH_REMOTE_ADDR6))
2590 return (EAFNOSUPPORT);
2571
2572 m_clrprotoflags(m);
2573 m->m_pkthdr.rcvif = ifp;
2574 M_SETFIB(m, ifp->if_fib);
2575
2576 error = netisr_queue_src(NETISR_ETHER, 0, m);
2577 *m0 = NULL;
2578

--- 35 unchanged lines hidden (view full) ---

2614 VXLAN_PARAM_WITH_REMOTE_ADDR4))
2615 return (EAFNOSUPPORT);
2616#endif
2617
2618#ifndef INET6
2619 if (vxlp->vxlp_with & (VXLAN_PARAM_WITH_LOCAL_ADDR6 |
2620 VXLAN_PARAM_WITH_REMOTE_ADDR6))
2621 return (EAFNOSUPPORT);
2622#else
2623 if (vxlp->vxlp_with & VXLAN_PARAM_WITH_LOCAL_ADDR6) {
2624 int error = vxlan_sockaddr_in6_embedscope(&vxlp->vxlp_local_sa);
2625 if (error)
2626 return (error);
2627 }
2628 if (vxlp->vxlp_with & VXLAN_PARAM_WITH_REMOTE_ADDR6) {
2629 int error = vxlan_sockaddr_in6_embedscope(
2630 &vxlp->vxlp_remote_sa);
2631 if (error)
2632 return (error);
2633 }
2591#endif
2592
2593 if (vxlp->vxlp_with & VXLAN_PARAM_WITH_VNI) {
2594 if (vxlan_check_vni(vxlp->vxlp_vni) == 0)
2595 sc->vxl_vni = vxlp->vxlp_vni;
2596 }
2597
2598 if (vxlp->vxlp_with & VXLAN_PARAM_WITH_LOCAL_ADDR4) {
2599 sc->vxl_src_addr.in4.sin_len = sizeof(struct sockaddr_in);
2600 sc->vxl_src_addr.in4.sin_family = AF_INET;
2634#endif
2635
2636 if (vxlp->vxlp_with & VXLAN_PARAM_WITH_VNI) {
2637 if (vxlan_check_vni(vxlp->vxlp_vni) == 0)
2638 sc->vxl_vni = vxlp->vxlp_vni;
2639 }
2640
2641 if (vxlp->vxlp_with & VXLAN_PARAM_WITH_LOCAL_ADDR4) {
2642 sc->vxl_src_addr.in4.sin_len = sizeof(struct sockaddr_in);
2643 sc->vxl_src_addr.in4.sin_family = AF_INET;
2601 sc->vxl_src_addr.in4.sin_addr = vxlp->vxlp_local_in4;
2644 sc->vxl_src_addr.in4.sin_addr =
2645 vxlp->vxlp_local_sa.in4.sin_addr;
2602 } else if (vxlp->vxlp_with & VXLAN_PARAM_WITH_LOCAL_ADDR6) {
2603 sc->vxl_src_addr.in6.sin6_len = sizeof(struct sockaddr_in6);
2604 sc->vxl_src_addr.in6.sin6_family = AF_INET6;
2646 } else if (vxlp->vxlp_with & VXLAN_PARAM_WITH_LOCAL_ADDR6) {
2647 sc->vxl_src_addr.in6.sin6_len = sizeof(struct sockaddr_in6);
2648 sc->vxl_src_addr.in6.sin6_family = AF_INET6;
2605 sc->vxl_src_addr.in6.sin6_addr = vxlp->vxlp_local_in6;
2649 sc->vxl_src_addr.in6.sin6_addr =
2650 vxlp->vxlp_local_sa.in6.sin6_addr;
2606 }
2607
2608 if (vxlp->vxlp_with & VXLAN_PARAM_WITH_REMOTE_ADDR4) {
2609 sc->vxl_dst_addr.in4.sin_len = sizeof(struct sockaddr_in);
2610 sc->vxl_dst_addr.in4.sin_family = AF_INET;
2651 }
2652
2653 if (vxlp->vxlp_with & VXLAN_PARAM_WITH_REMOTE_ADDR4) {
2654 sc->vxl_dst_addr.in4.sin_len = sizeof(struct sockaddr_in);
2655 sc->vxl_dst_addr.in4.sin_family = AF_INET;
2611 sc->vxl_dst_addr.in4.sin_addr = vxlp->vxlp_remote_in4;
2656 sc->vxl_dst_addr.in4.sin_addr =
2657 vxlp->vxlp_remote_sa.in4.sin_addr;
2612 } else if (vxlp->vxlp_with & VXLAN_PARAM_WITH_REMOTE_ADDR6) {
2613 sc->vxl_dst_addr.in6.sin6_len = sizeof(struct sockaddr_in6);
2614 sc->vxl_dst_addr.in6.sin6_family = AF_INET6;
2658 } else if (vxlp->vxlp_with & VXLAN_PARAM_WITH_REMOTE_ADDR6) {
2659 sc->vxl_dst_addr.in6.sin6_len = sizeof(struct sockaddr_in6);
2660 sc->vxl_dst_addr.in6.sin6_family = AF_INET6;
2615 sc->vxl_dst_addr.in6.sin6_addr = vxlp->vxlp_remote_in6;
2661 sc->vxl_dst_addr.in6.sin6_addr =
2662 vxlp->vxlp_remote_sa.in6.sin6_addr;
2616 }
2617
2618 if (vxlp->vxlp_with & VXLAN_PARAM_WITH_LOCAL_PORT)
2619 sc->vxl_src_addr.in4.sin_port = htons(vxlp->vxlp_local_port);
2620 if (vxlp->vxlp_with & VXLAN_PARAM_WITH_REMOTE_PORT)
2621 sc->vxl_dst_addr.in4.sin_port = htons(vxlp->vxlp_remote_port);
2622
2623 if (vxlp->vxlp_with & VXLAN_PARAM_WITH_PORT_RANGE) {

--- 302 unchanged lines hidden (view full) ---

2926 mc = IN6_IS_ADDR_MULTICAST(in6);
2927 } else
2928 mc = -1;
2929
2930 return (mc);
2931}
2932
2933static int
2663 }
2664
2665 if (vxlp->vxlp_with & VXLAN_PARAM_WITH_LOCAL_PORT)
2666 sc->vxl_src_addr.in4.sin_port = htons(vxlp->vxlp_local_port);
2667 if (vxlp->vxlp_with & VXLAN_PARAM_WITH_REMOTE_PORT)
2668 sc->vxl_dst_addr.in4.sin_port = htons(vxlp->vxlp_remote_port);
2669
2670 if (vxlp->vxlp_with & VXLAN_PARAM_WITH_PORT_RANGE) {

--- 302 unchanged lines hidden (view full) ---

2973 mc = IN6_IS_ADDR_MULTICAST(in6);
2974 } else
2975 mc = -1;
2976
2977 return (mc);
2978}
2979
2980static int
2981vxlan_sockaddr_in6_embedscope(union vxlan_sockaddr *vxladdr)
2982{
2983 int error;
2984
2985 MPASS(VXLAN_SOCKADDR_IS_IPV6(vxladdr));
2986#ifdef INET6
2987 error = sa6_embedscope(&vxladdr->in6, V_ip6_use_defzone);
2988#else
2989 error = EAFNOSUPPORT;
2990#endif
2991
2992 return (error);
2993}
2994
2995static int
2934vxlan_can_change_config(struct vxlan_softc *sc)
2935{
2936 struct ifnet *ifp;
2937
2938 ifp = sc->vxl_ifp;
2939 VXLAN_LOCK_ASSERT(sc);
2940
2941 if (ifp->if_drv_flags & IFF_DRV_RUNNING)

--- 181 unchanged lines hidden ---
2996vxlan_can_change_config(struct vxlan_softc *sc)
2997{
2998 struct ifnet *ifp;
2999
3000 ifp = sc->vxl_ifp;
3001 VXLAN_LOCK_ASSERT(sc);
3002
3003 if (ifp->if_drv_flags & IFF_DRV_RUNNING)

--- 181 unchanged lines hidden ---