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 --- |