if.c (130585) | if.c (130933) |
---|---|
1/* 2 * Copyright (c) 1980, 1986, 1993 3 * The Regents of the University of California. 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 --- 13 unchanged lines hidden (view full) --- 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)if.c 8.5 (Berkeley) 1/9/95 | 1/* 2 * Copyright (c) 1980, 1986, 1993 3 * The Regents of the University of California. 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 --- 13 unchanged lines hidden (view full) --- 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)if.c 8.5 (Berkeley) 1/9/95 |
30 * $FreeBSD: head/sys/net/if.c 130585 2004-06-16 09:47:26Z phk $ | 30 * $FreeBSD: head/sys/net/if.c 130933 2004-06-22 20:13:25Z brooks $ |
31 */ 32 33#include "opt_compat.h" 34#include "opt_inet6.h" 35#include "opt_inet.h" 36#include "opt_mac.h" 37 38#include <sys/param.h> --- 12 unchanged lines hidden (view full) --- 51#include <sys/syslog.h> 52#include <sys/sysctl.h> 53#include <sys/domain.h> 54#include <sys/jail.h> 55#include <machine/stdarg.h> 56 57#include <net/if.h> 58#include <net/if_arp.h> | 31 */ 32 33#include "opt_compat.h" 34#include "opt_inet6.h" 35#include "opt_inet.h" 36#include "opt_mac.h" 37 38#include <sys/param.h> --- 12 unchanged lines hidden (view full) --- 51#include <sys/syslog.h> 52#include <sys/sysctl.h> 53#include <sys/domain.h> 54#include <sys/jail.h> 55#include <machine/stdarg.h> 56 57#include <net/if.h> 58#include <net/if_arp.h> |
59#include <net/if_clone.h> |
|
59#include <net/if_dl.h> 60#include <net/if_types.h> 61#include <net/if_var.h> 62#include <net/radix.h> 63#include <net/route.h> 64 65#if defined(INET) || defined(INET6) 66/*XXX*/ --- 18 unchanged lines hidden (view full) --- 85static void if_check(void *); 86static int if_findindex(struct ifnet *); 87static void if_qflush(struct ifaltq *); 88static void if_route(struct ifnet *, int flag, int fam); 89static void if_slowtimo(void *); 90static void if_unroute(struct ifnet *, int flag, int fam); 91static void link_rtrequest(int, struct rtentry *, struct rt_addrinfo *); 92static int if_rtdel(struct radix_node *, void *); | 60#include <net/if_dl.h> 61#include <net/if_types.h> 62#include <net/if_var.h> 63#include <net/radix.h> 64#include <net/route.h> 65 66#if defined(INET) || defined(INET6) 67/*XXX*/ --- 18 unchanged lines hidden (view full) --- 86static void if_check(void *); 87static int if_findindex(struct ifnet *); 88static void if_qflush(struct ifaltq *); 89static void if_route(struct ifnet *, int flag, int fam); 90static void if_slowtimo(void *); 91static void if_unroute(struct ifnet *, int flag, int fam); 92static void link_rtrequest(int, struct rtentry *, struct rt_addrinfo *); 93static int if_rtdel(struct radix_node *, void *); |
93static struct if_clone *if_clone_lookup(const char *, int *); 94static int if_clone_list(struct if_clonereq *); | |
95static int ifhwioctl(u_long, struct ifnet *, caddr_t, struct thread *); 96#ifdef INET6 97/* 98 * XXX: declare here to avoid to include many inet6 related files.. 99 * should be more generalized? 100 */ 101extern void nd6_setmtu(struct ifnet *); 102#endif 103 104int if_index = 0; 105struct ifindex_entry *ifindex_table = NULL; 106int ifqmaxlen = IFQ_MAXLEN; 107struct ifnethead ifnet; /* depend on static init XXX */ 108struct mtx ifnet_lock; | 94static int ifhwioctl(u_long, struct ifnet *, caddr_t, struct thread *); 95#ifdef INET6 96/* 97 * XXX: declare here to avoid to include many inet6 related files.. 98 * should be more generalized? 99 */ 100extern void nd6_setmtu(struct ifnet *); 101#endif 102 103int if_index = 0; 104struct ifindex_entry *ifindex_table = NULL; 105int ifqmaxlen = IFQ_MAXLEN; 106struct ifnethead ifnet; /* depend on static init XXX */ 107struct mtx ifnet_lock; |
109static int if_cloners_count; 110LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners); | |
111 112static int if_indexlim = 8; 113static struct klist ifklist; 114 115static void filt_netdetach(struct knote *kn); 116static int filt_netdev(struct knote *kn, long hint); 117 118static struct filterops netdev_filtops = 119 { 1, NULL, filt_netdetach, filt_netdev }; 120 121/* 122 * System initialization 123 */ 124SYSINIT(interfaces, SI_SUB_INIT_IF, SI_ORDER_FIRST, if_init, NULL) 125SYSINIT(interface_check, SI_SUB_PROTO_IF, SI_ORDER_FIRST, if_check, NULL) 126 127MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address"); 128MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address"); | 108 109static int if_indexlim = 8; 110static struct klist ifklist; 111 112static void filt_netdetach(struct knote *kn); 113static int filt_netdev(struct knote *kn, long hint); 114 115static struct filterops netdev_filtops = 116 { 1, NULL, filt_netdetach, filt_netdev }; 117 118/* 119 * System initialization 120 */ 121SYSINIT(interfaces, SI_SUB_INIT_IF, SI_ORDER_FIRST, if_init, NULL) 122SYSINIT(interface_check, SI_SUB_PROTO_IF, SI_ORDER_FIRST, if_check, NULL) 123 124MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address"); 125MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address"); |
129MALLOC_DEFINE(M_CLONE, "clone", "interface cloning framework"); | |
130 131static d_open_t netopen; 132static d_close_t netclose; 133static d_ioctl_t netioctl; 134static d_kqfilter_t netkqfilter; 135 136static struct cdevsw net_cdevsw = { 137 .d_version = D_VERSION, --- 120 unchanged lines hidden (view full) --- 258{ 259 260 IFNET_LOCK_INIT(); 261 TAILQ_INIT(&ifnet); 262 SLIST_INIT(&ifklist); 263 if_grow(); /* create initial table */ 264 ifdev_byindex(0) = make_dev(&net_cdevsw, 0, 265 UID_ROOT, GID_WHEEL, 0600, "network"); | 126 127static d_open_t netopen; 128static d_close_t netclose; 129static d_ioctl_t netioctl; 130static d_kqfilter_t netkqfilter; 131 132static struct cdevsw net_cdevsw = { 133 .d_version = D_VERSION, --- 120 unchanged lines hidden (view full) --- 254{ 255 256 IFNET_LOCK_INIT(); 257 TAILQ_INIT(&ifnet); 258 SLIST_INIT(&ifklist); 259 if_grow(); /* create initial table */ 260 ifdev_byindex(0) = make_dev(&net_cdevsw, 0, 261 UID_ROOT, GID_WHEEL, 0600, "network"); |
262 if_clone_init(); |
|
266} 267 268static void 269if_grow(void) 270{ 271 u_int n; 272 struct ifindex_entry *e; 273 --- 389 unchanged lines hidden (view full) --- 663 if (err) { 664 log(LOG_WARNING, "if_rtdel: error %d\n", err); 665 } 666 } 667 668 return (0); 669} 670 | 263} 264 265static void 266if_grow(void) 267{ 268 u_int n; 269 struct ifindex_entry *e; 270 --- 389 unchanged lines hidden (view full) --- 660 if (err) { 661 log(LOG_WARNING, "if_rtdel: error %d\n", err); 662 } 663 } 664 665 return (0); 666} 667 |
671/* 672 * Create a clone network interface. 673 */ 674int 675if_clone_create(char *name, int len) 676{ 677 struct if_clone *ifc; 678 char *dp; 679 int wildcard, bytoff, bitoff; 680 int unit; 681 int err; 682 683 ifc = if_clone_lookup(name, &unit); 684 if (ifc == NULL) 685 return (EINVAL); 686 687 if (ifunit(name) != NULL) 688 return (EEXIST); 689 690 bytoff = bitoff = 0; 691 wildcard = (unit < 0); 692 /* 693 * Find a free unit if none was given. 694 */ 695 if (wildcard) { 696 while ((bytoff < ifc->ifc_bmlen) 697 && (ifc->ifc_units[bytoff] == 0xff)) 698 bytoff++; 699 if (bytoff >= ifc->ifc_bmlen) 700 return (ENOSPC); 701 while ((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0) 702 bitoff++; 703 unit = (bytoff << 3) + bitoff; 704 } 705 706 if (unit > ifc->ifc_maxunit) 707 return (ENXIO); 708 709 err = (*ifc->ifc_create)(ifc, unit); 710 if (err != 0) 711 return (err); 712 713 if (!wildcard) { 714 bytoff = unit >> 3; 715 bitoff = unit - (bytoff << 3); 716 } 717 718 /* 719 * Allocate the unit in the bitmap. 720 */ 721 KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) == 0, 722 ("%s: bit is already set", __func__)); 723 ifc->ifc_units[bytoff] |= (1 << bitoff); 724 725 /* In the wildcard case, we need to update the name. */ 726 if (wildcard) { 727 for (dp = name; *dp != '\0'; dp++); 728 if (snprintf(dp, len - (dp-name), "%d", unit) > 729 len - (dp-name) - 1) { 730 /* 731 * This can only be a programmer error and 732 * there's no straightforward way to recover if 733 * it happens. 734 */ 735 panic("if_clone_create(): interface name too long"); 736 } 737 738 } 739 740 return (0); 741} 742 743/* 744 * Destroy a clone network interface. 745 */ 746int 747if_clone_destroy(const char *name) 748{ 749 struct if_clone *ifc; 750 struct ifnet *ifp; 751 int bytoff, bitoff; 752 int unit; 753 754 ifp = ifunit(name); 755 if (ifp == NULL) 756 return (ENXIO); 757 758 unit = ifp->if_dunit; 759 760 ifc = if_clone_lookup(ifp->if_dname, NULL); 761 if (ifc == NULL) 762 return (EINVAL); 763 764 if (ifc->ifc_destroy == NULL) 765 return (EOPNOTSUPP); 766 767 (*ifc->ifc_destroy)(ifp); 768 769 /* 770 * Compute offset in the bitmap and deallocate the unit. 771 */ 772 bytoff = unit >> 3; 773 bitoff = unit - (bytoff << 3); 774 KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0, 775 ("%s: bit is already cleared", __func__)); 776 ifc->ifc_units[bytoff] &= ~(1 << bitoff); 777 return (0); 778} 779 780/* 781 * Look up a network interface cloner. 782 */ 783static struct if_clone * 784if_clone_lookup(const char *name, int *unitp) 785{ 786 struct if_clone *ifc; 787 const char *cp; 788 int i; 789 790 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL;) { 791 for (cp = name, i = 0; i < ifc->ifc_namelen; i++, cp++) { 792 if (ifc->ifc_name[i] != *cp) 793 goto next_ifc; 794 } 795 goto found_name; 796 next_ifc: 797 ifc = LIST_NEXT(ifc, ifc_list); 798 } 799 800 /* No match. */ 801 return ((struct if_clone *)NULL); 802 803 found_name: 804 if (*cp == '\0') { 805 i = -1; 806 } else { 807 for (i = 0; *cp != '\0'; cp++) { 808 if (*cp < '0' || *cp > '9') { 809 /* Bogus unit number. */ 810 return (NULL); 811 } 812 i = (i * 10) + (*cp - '0'); 813 } 814 } 815 816 if (unitp != NULL) 817 *unitp = i; 818 return (ifc); 819} 820 821/* 822 * Register a network interface cloner. 823 */ 824void 825if_clone_attach(struct if_clone *ifc) 826{ 827 int bytoff, bitoff; 828 int err; 829 int len, maxclone; 830 int unit; 831 832 KASSERT(ifc->ifc_minifs - 1 <= ifc->ifc_maxunit, 833 ("%s: %s requested more units then allowed (%d > %d)", 834 __func__, ifc->ifc_name, ifc->ifc_minifs, 835 ifc->ifc_maxunit + 1)); 836 /* 837 * Compute bitmap size and allocate it. 838 */ 839 maxclone = ifc->ifc_maxunit + 1; 840 len = maxclone >> 3; 841 if ((len << 3) < maxclone) 842 len++; 843 ifc->ifc_units = malloc(len, M_CLONE, M_WAITOK | M_ZERO); 844 ifc->ifc_bmlen = len; 845 846 LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list); 847 if_cloners_count++; 848 849 for (unit = 0; unit < ifc->ifc_minifs; unit++) { 850 err = (*ifc->ifc_create)(ifc, unit); 851 KASSERT(err == 0, 852 ("%s: failed to create required interface %s%d", 853 __func__, ifc->ifc_name, unit)); 854 855 /* Allocate the unit in the bitmap. */ 856 bytoff = unit >> 3; 857 bitoff = unit - (bytoff << 3); 858 ifc->ifc_units[bytoff] |= (1 << bitoff); 859 } 860 EVENTHANDLER_INVOKE(if_clone_event, ifc); 861} 862 863/* 864 * Unregister a network interface cloner. 865 */ 866void 867if_clone_detach(struct if_clone *ifc) 868{ 869 870 LIST_REMOVE(ifc, ifc_list); 871 free(ifc->ifc_units, M_CLONE); 872 if_cloners_count--; 873} 874 875/* 876 * Provide list of interface cloners to userspace. 877 */ 878static int 879if_clone_list(struct if_clonereq *ifcr) 880{ 881 char outbuf[IFNAMSIZ], *dst; 882 struct if_clone *ifc; 883 int count, error = 0; 884 885 ifcr->ifcr_total = if_cloners_count; 886 if ((dst = ifcr->ifcr_buffer) == NULL) { 887 /* Just asking how many there are. */ 888 return (0); 889 } 890 891 if (ifcr->ifcr_count < 0) 892 return (EINVAL); 893 894 count = (if_cloners_count < ifcr->ifcr_count) ? 895 if_cloners_count : ifcr->ifcr_count; 896 897 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0; 898 ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) { 899 strlcpy(outbuf, ifc->ifc_name, IFNAMSIZ); 900 error = copyout(outbuf, dst, IFNAMSIZ); 901 if (error) 902 break; 903 } 904 905 return (error); 906} 907 | |
908#define equal(a1, a2) (bcmp((a1), (a2), ((a1))->sa_len) == 0) 909 910/* 911 * Locate an interface based on a complete address. 912 */ 913/*ARGSUSED*/ 914struct ifaddr * 915ifa_ifwithaddr(struct sockaddr *addr) --- 1169 unchanged lines hidden --- | 668#define equal(a1, a2) (bcmp((a1), (a2), ((a1))->sa_len) == 0) 669 670/* 671 * Locate an interface based on a complete address. 672 */ 673/*ARGSUSED*/ 674struct ifaddr * 675ifa_ifwithaddr(struct sockaddr *addr) --- 1169 unchanged lines hidden --- |