Deleted Added
full compact
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);