if_epair.c (241394) | if_epair.c (241610) |
---|---|
1/*- 2 * Copyright (c) 2008 The FreeBSD Foundation 3 * Copyright (c) 2009-2010 Bjoern A. Zeeb <bz@FreeBSD.org> 4 * All rights reserved. 5 * 6 * This software was developed by CK Software GmbH under sponsorship 7 * from the FreeBSD Foundation. 8 * --- 34 unchanged lines hidden (view full) --- 43 * to re-do them in case we move the interface between network stacks 44 * in a private if_reassign function. 45 * In case we bridge to a real interface/network or between indepedent 46 * epairs on multiple stacks/machines, we may need this. 47 * For now let the user handle that case. 48 */ 49 50#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2008 The FreeBSD Foundation 3 * Copyright (c) 2009-2010 Bjoern A. Zeeb <bz@FreeBSD.org> 4 * All rights reserved. 5 * 6 * This software was developed by CK Software GmbH under sponsorship 7 * from the FreeBSD Foundation. 8 * --- 34 unchanged lines hidden (view full) --- 43 * to re-do them in case we move the interface between network stacks 44 * in a private if_reassign function. 45 * In case we bridge to a real interface/network or between indepedent 46 * epairs on multiple stacks/machines, we may need this. 47 * For now let the user handle that case. 48 */ 49 50#include <sys/cdefs.h> |
51__FBSDID("$FreeBSD: head/sys/net/if_epair.c 241394 2012-10-10 08:36:38Z kevlo $"); | 51__FBSDID("$FreeBSD: head/sys/net/if_epair.c 241610 2012-10-16 13:37:54Z glebius $"); |
52 53#include <sys/param.h> 54#include <sys/kernel.h> 55#include <sys/mbuf.h> 56#include <sys/module.h> 57#include <sys/refcount.h> 58#include <sys/queue.h> 59#include <sys/smp.h> --- 7 unchanged lines hidden (view full) --- 67#include <net/if.h> 68#include <net/if_clone.h> 69#include <net/if_media.h> 70#include <net/if_var.h> 71#include <net/if_types.h> 72#include <net/netisr.h> 73#include <net/vnet.h> 74 | 52 53#include <sys/param.h> 54#include <sys/kernel.h> 55#include <sys/mbuf.h> 56#include <sys/module.h> 57#include <sys/refcount.h> 58#include <sys/queue.h> 59#include <sys/smp.h> --- 7 unchanged lines hidden (view full) --- 67#include <net/if.h> 68#include <net/if_clone.h> 69#include <net/if_media.h> 70#include <net/if_var.h> 71#include <net/if_types.h> 72#include <net/netisr.h> 73#include <net/vnet.h> 74 |
75#define EPAIRNAME "epair" 76 | |
77SYSCTL_DECL(_net_link); 78static SYSCTL_NODE(_net_link, OID_AUTO, epair, CTLFLAG_RW, 0, "epair sysctl"); 79 80#ifdef EPAIR_DEBUG 81static int epair_debug = 0; 82SYSCTL_INT(_net_link_epair, OID_AUTO, epair_debug, CTLFLAG_RW, 83 &epair_debug, 0, "if_epair(4) debugging."); 84#define DPRINTF(fmt, arg...) \ --- 10 unchanged lines hidden (view full) --- 95static void epair_start_locked(struct ifnet *); 96static int epair_media_change(struct ifnet *); 97static void epair_media_status(struct ifnet *, struct ifmediareq *); 98 99static int epair_clone_match(struct if_clone *, const char *); 100static int epair_clone_create(struct if_clone *, char *, size_t, caddr_t); 101static int epair_clone_destroy(struct if_clone *, struct ifnet *); 102 | 75SYSCTL_DECL(_net_link); 76static SYSCTL_NODE(_net_link, OID_AUTO, epair, CTLFLAG_RW, 0, "epair sysctl"); 77 78#ifdef EPAIR_DEBUG 79static int epair_debug = 0; 80SYSCTL_INT(_net_link_epair, OID_AUTO, epair_debug, CTLFLAG_RW, 81 &epair_debug, 0, "if_epair(4) debugging."); 82#define DPRINTF(fmt, arg...) \ --- 10 unchanged lines hidden (view full) --- 93static void epair_start_locked(struct ifnet *); 94static int epair_media_change(struct ifnet *); 95static void epair_media_status(struct ifnet *, struct ifmediareq *); 96 97static int epair_clone_match(struct if_clone *, const char *); 98static int epair_clone_create(struct if_clone *, char *, size_t, caddr_t); 99static int epair_clone_destroy(struct if_clone *, struct ifnet *); 100 |
101static const char epairname[] = "epair"; 102 |
|
103/* Netisr realted definitions and sysctl. */ 104static struct netisr_handler epair_nh = { | 103/* Netisr realted definitions and sysctl. */ 104static struct netisr_handler epair_nh = { |
105 .nh_name = EPAIRNAME, | 105 .nh_name = epairname, |
106 .nh_proto = NETISR_EPAIR, 107 .nh_policy = NETISR_POLICY_CPU, 108 .nh_handler = epair_nh_sintr, 109 .nh_m2cpuid = epair_nh_m2cpuid, 110 .nh_drainedcpu = epair_nh_drainedcpu, 111}; 112 113static int --- 49 unchanged lines hidden (view full) --- 163#define EPAIR_REFCOUNT_ASSERT(a, p) KASSERT(a, p) 164#else 165#define EPAIR_REFCOUNT_INIT(r, v) 166#define EPAIR_REFCOUNT_AQUIRE(r) 167#define EPAIR_REFCOUNT_RELEASE(r) 168#define EPAIR_REFCOUNT_ASSERT(a, p) 169#endif 170 | 106 .nh_proto = NETISR_EPAIR, 107 .nh_policy = NETISR_POLICY_CPU, 108 .nh_handler = epair_nh_sintr, 109 .nh_m2cpuid = epair_nh_m2cpuid, 110 .nh_drainedcpu = epair_nh_drainedcpu, 111}; 112 113static int --- 49 unchanged lines hidden (view full) --- 163#define EPAIR_REFCOUNT_ASSERT(a, p) KASSERT(a, p) 164#else 165#define EPAIR_REFCOUNT_INIT(r, v) 166#define EPAIR_REFCOUNT_AQUIRE(r) 167#define EPAIR_REFCOUNT_RELEASE(r) 168#define EPAIR_REFCOUNT_ASSERT(a, p) 169#endif 170 |
171static MALLOC_DEFINE(M_EPAIR, EPAIRNAME, | 171static MALLOC_DEFINE(M_EPAIR, epairname, |
172 "Pair of virtual cross-over connected Ethernet-like interfaces"); 173 | 172 "Pair of virtual cross-over connected Ethernet-like interfaces"); 173 |
174static struct if_clone epair_cloner = IFC_CLONE_INITIALIZER( 175 EPAIRNAME, NULL, IF_MAXUNIT, 176 NULL, epair_clone_match, epair_clone_create, epair_clone_destroy); | 174static struct if_clone *epair_cloner; |
177 178/* 179 * DPCPU area and functions. 180 */ 181struct epair_dpcpu { 182 struct mtx if_epair_mtx; /* Per-CPU locking. */ 183 int epair_drv_flags; /* Per-CPU ``hw'' drv flags. */ 184 struct eid_list epair_ifp_drain_list; /* Per-CPU list of ifps with --- 502 unchanged lines hidden (view full) --- 687 /* 688 * Our base name is epair. 689 * Our interfaces will be named epair<n>[ab]. 690 * So accept anything of the following list: 691 * - epair 692 * - epair<n> 693 * but not the epair<n>[ab] versions. 694 */ | 175 176/* 177 * DPCPU area and functions. 178 */ 179struct epair_dpcpu { 180 struct mtx if_epair_mtx; /* Per-CPU locking. */ 181 int epair_drv_flags; /* Per-CPU ``hw'' drv flags. */ 182 struct eid_list epair_ifp_drain_list; /* Per-CPU list of ifps with --- 502 unchanged lines hidden (view full) --- 685 /* 686 * Our base name is epair. 687 * Our interfaces will be named epair<n>[ab]. 688 * So accept anything of the following list: 689 * - epair 690 * - epair<n> 691 * but not the epair<n>[ab] versions. 692 */ |
695 if (strncmp(EPAIRNAME, name, sizeof(EPAIRNAME)-1) != 0) | 693 if (strncmp(epairname, name, sizeof(epairname)-1) != 0) |
696 return (0); 697 | 694 return (0); 695 |
698 for (cp = name + sizeof(EPAIRNAME) - 1; *cp != '\0'; cp++) { | 696 for (cp = name + sizeof(epairname) - 1; *cp != '\0'; cp++) { |
699 if (*cp < '0' || *cp > '9') 700 return (0); 701 } 702 703 return (1); 704} 705 706static int 707epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) 708{ 709 struct epair_softc *sca, *scb; 710 struct ifnet *ifp; 711 char *dp; 712 int error, unit, wildcard; 713 uint8_t eaddr[ETHER_ADDR_LEN]; /* 00:00:00:00:00:00 */ 714 715 /* 716 * We are abusing params to create our second interface. | 697 if (*cp < '0' || *cp > '9') 698 return (0); 699 } 700 701 return (1); 702} 703 704static int 705epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) 706{ 707 struct epair_softc *sca, *scb; 708 struct ifnet *ifp; 709 char *dp; 710 int error, unit, wildcard; 711 uint8_t eaddr[ETHER_ADDR_LEN]; /* 00:00:00:00:00:00 */ 712 713 /* 714 * We are abusing params to create our second interface. |
717 * Actually we already created it and called if_clone_createif() | 715 * Actually we already created it and called if_clone_create() |
718 * for it to do the official insertion procedure the moment we knew 719 * it cannot fail anymore. So just do attach it here. 720 */ 721 if (params) { 722 scb = (struct epair_softc *)params; 723 ifp = scb->ifp; 724 /* Assign a hopefully unique, locally administered etheraddr. */ 725 eaddr[0] = 0x02; --- 76 unchanged lines hidden (view full) --- 802 netisr_get_cpuid(sca->ifp->if_index % netisr_get_cpucount()); 803 scb->cpuid = 804 netisr_get_cpuid(scb->ifp->if_index % netisr_get_cpucount()); 805 806 /* Finish initialization of interface <n>a. */ 807 ifp = sca->ifp; 808 ifp->if_softc = sca; 809 strlcpy(ifp->if_xname, name, IFNAMSIZ); | 716 * for it to do the official insertion procedure the moment we knew 717 * it cannot fail anymore. So just do attach it here. 718 */ 719 if (params) { 720 scb = (struct epair_softc *)params; 721 ifp = scb->ifp; 722 /* Assign a hopefully unique, locally administered etheraddr. */ 723 eaddr[0] = 0x02; --- 76 unchanged lines hidden (view full) --- 800 netisr_get_cpuid(sca->ifp->if_index % netisr_get_cpucount()); 801 scb->cpuid = 802 netisr_get_cpuid(scb->ifp->if_index % netisr_get_cpucount()); 803 804 /* Finish initialization of interface <n>a. */ 805 ifp = sca->ifp; 806 ifp->if_softc = sca; 807 strlcpy(ifp->if_xname, name, IFNAMSIZ); |
810 ifp->if_dname = ifc->ifc_name; | 808 ifp->if_dname = epairname; |
811 ifp->if_dunit = unit; 812 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 813 ifp->if_capabilities = IFCAP_VLAN_MTU; 814 ifp->if_capenable = IFCAP_VLAN_MTU; 815 ifp->if_start = epair_start; 816 ifp->if_ioctl = epair_ioctl; 817 ifp->if_init = epair_init; 818 ifp->if_snd.ifq_maxlen = ifqmaxlen; --- 9 unchanged lines hidden (view full) --- 828 ifp->if_baudrate = IF_Gbps(10UL); /* arbitrary maximum */ 829 830 /* Swap the name and finish initialization of interface <n>b. */ 831 *dp = 'b'; 832 833 ifp = scb->ifp; 834 ifp->if_softc = scb; 835 strlcpy(ifp->if_xname, name, IFNAMSIZ); | 809 ifp->if_dunit = unit; 810 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 811 ifp->if_capabilities = IFCAP_VLAN_MTU; 812 ifp->if_capenable = IFCAP_VLAN_MTU; 813 ifp->if_start = epair_start; 814 ifp->if_ioctl = epair_ioctl; 815 ifp->if_init = epair_init; 816 ifp->if_snd.ifq_maxlen = ifqmaxlen; --- 9 unchanged lines hidden (view full) --- 826 ifp->if_baudrate = IF_Gbps(10UL); /* arbitrary maximum */ 827 828 /* Swap the name and finish initialization of interface <n>b. */ 829 *dp = 'b'; 830 831 ifp = scb->ifp; 832 ifp->if_softc = scb; 833 strlcpy(ifp->if_xname, name, IFNAMSIZ); |
836 ifp->if_dname = ifc->ifc_name; | 834 ifp->if_dname = epairname; |
837 ifp->if_dunit = unit; 838 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 839 ifp->if_capabilities = IFCAP_VLAN_MTU; 840 ifp->if_capenable = IFCAP_VLAN_MTU; 841 ifp->if_start = epair_start; 842 ifp->if_ioctl = epair_ioctl; 843 ifp->if_init = epair_init; 844 ifp->if_snd.ifq_maxlen = ifqmaxlen; 845 /* We need to play some tricks here for the second interface. */ | 835 ifp->if_dunit = unit; 836 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 837 ifp->if_capabilities = IFCAP_VLAN_MTU; 838 ifp->if_capenable = IFCAP_VLAN_MTU; 839 ifp->if_start = epair_start; 840 ifp->if_ioctl = epair_ioctl; 841 ifp->if_init = epair_init; 842 ifp->if_snd.ifq_maxlen = ifqmaxlen; 843 /* We need to play some tricks here for the second interface. */ |
846 strlcpy(name, EPAIRNAME, len); | 844 strlcpy(name, epairname, len); |
847 error = if_clone_create(name, len, (caddr_t)scb); 848 if (error) | 845 error = if_clone_create(name, len, (caddr_t)scb); 846 if (error) |
849 panic("%s: if_clone_createif() for our 2nd iface failed: %d", | 847 panic("%s: if_clone_create() for our 2nd iface failed: %d", |
850 __func__, error); 851 scb->if_qflush = ifp->if_qflush; 852 ifp->if_qflush = epair_qflush; 853 ifp->if_transmit = epair_transmit; 854 ifp->if_baudrate = IF_Gbps(10UL); /* arbitrary maximum */ 855 856 /* 857 * Restore name to <n>a as the ifp for this will go into the --- 95 unchanged lines hidden (view full) --- 953 switch (type) { 954 case MOD_LOAD: 955 /* For now limit us to one global mutex and one inq. */ 956 epair_dpcpu_init(); 957 epair_nh.nh_qlimit = 42 * ifqmaxlen; /* 42 shall be the number. */ 958 if (TUNABLE_INT_FETCH("net.link.epair.netisr_maxqlen", &qlimit)) 959 epair_nh.nh_qlimit = qlimit; 960 netisr_register(&epair_nh); | 848 __func__, error); 849 scb->if_qflush = ifp->if_qflush; 850 ifp->if_qflush = epair_qflush; 851 ifp->if_transmit = epair_transmit; 852 ifp->if_baudrate = IF_Gbps(10UL); /* arbitrary maximum */ 853 854 /* 855 * Restore name to <n>a as the ifp for this will go into the --- 95 unchanged lines hidden (view full) --- 951 switch (type) { 952 case MOD_LOAD: 953 /* For now limit us to one global mutex and one inq. */ 954 epair_dpcpu_init(); 955 epair_nh.nh_qlimit = 42 * ifqmaxlen; /* 42 shall be the number. */ 956 if (TUNABLE_INT_FETCH("net.link.epair.netisr_maxqlen", &qlimit)) 957 epair_nh.nh_qlimit = qlimit; 958 netisr_register(&epair_nh); |
961 if_clone_attach(&epair_cloner); | 959 epair_cloner = if_clone_advanced(epairname, 0, 960 epair_clone_match, epair_clone_create, epair_clone_destroy); |
962 if (bootverbose) | 961 if (bootverbose) |
963 printf("%s initialized.\n", EPAIRNAME); | 962 printf("%s initialized.\n", epairname); |
964 break; 965 case MOD_UNLOAD: | 963 break; 964 case MOD_UNLOAD: |
966 if_clone_detach(&epair_cloner); | 965 if_clone_detach(epair_cloner); |
967 netisr_unregister(&epair_nh); 968 epair_dpcpu_detach(); 969 if (bootverbose) | 966 netisr_unregister(&epair_nh); 967 epair_dpcpu_detach(); 968 if (bootverbose) |
970 printf("%s unloaded.\n", EPAIRNAME); | 969 printf("%s unloaded.\n", epairname); |
971 break; 972 default: 973 return (EOPNOTSUPP); 974 } 975 return (0); 976} 977 978static moduledata_t epair_mod = { 979 "if_epair", 980 epair_modevent, 981 0 982}; 983 984DECLARE_MODULE(if_epair, epair_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 985MODULE_VERSION(if_epair, 1); | 970 break; 971 default: 972 return (EOPNOTSUPP); 973 } 974 return (0); 975} 976 977static moduledata_t epair_mod = { 978 "if_epair", 979 epair_modevent, 980 0 981}; 982 983DECLARE_MODULE(if_epair, epair_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 984MODULE_VERSION(if_epair, 1); |