Deleted Added
full compact
if.c (159528) if.c (159781)
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 159528 2006-06-11 22:09:28Z fjoe $
30 * $FreeBSD: head/sys/net/if.c 159781 2006-06-19 22:20:45Z mlaier $
31 */
32
33#include "opt_compat.h"
34#include "opt_inet6.h"
35#include "opt_inet.h"
36#include "opt_mac.h"
37#include "opt_carp.h"
38

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

108static int if_setflag(struct ifnet *, int, int, int *, int);
109static void if_slowtimo(void *);
110static void if_unroute(struct ifnet *, int flag, int fam);
111static void link_rtrequest(int, struct rtentry *, struct rt_addrinfo *);
112static int if_rtdel(struct radix_node *, void *);
113static int ifhwioctl(u_long, struct ifnet *, caddr_t, struct thread *);
114static void if_start_deferred(void *context, int pending);
115static void do_link_state_change(void *, int);
31 */
32
33#include "opt_compat.h"
34#include "opt_inet6.h"
35#include "opt_inet.h"
36#include "opt_mac.h"
37#include "opt_carp.h"
38

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

108static int if_setflag(struct ifnet *, int, int, int *, int);
109static void if_slowtimo(void *);
110static void if_unroute(struct ifnet *, int flag, int fam);
111static void link_rtrequest(int, struct rtentry *, struct rt_addrinfo *);
112static int if_rtdel(struct radix_node *, void *);
113static int ifhwioctl(u_long, struct ifnet *, caddr_t, struct thread *);
114static void if_start_deferred(void *context, int pending);
115static void do_link_state_change(void *, int);
116static int if_getgroup(struct ifgroupreq *, struct ifnet *);
117static int if_getgroupmembers(struct ifgroupreq *);
116#ifdef INET6
117/*
118 * XXX: declare here to avoid to include many inet6 related files..
119 * should be more generalized?
120 */
121extern void nd6_setmtu(struct ifnet *);
122#endif
123
124int if_index = 0;
125struct ifindex_entry *ifindex_table = NULL;
126int ifqmaxlen = IFQ_MAXLEN;
127struct ifnethead ifnet; /* depend on static init XXX */
118#ifdef INET6
119/*
120 * XXX: declare here to avoid to include many inet6 related files..
121 * should be more generalized?
122 */
123extern void nd6_setmtu(struct ifnet *);
124#endif
125
126int if_index = 0;
127struct ifindex_entry *ifindex_table = NULL;
128int ifqmaxlen = IFQ_MAXLEN;
129struct ifnethead ifnet; /* depend on static init XXX */
130struct ifgrouphead ifg_head;
128struct mtx ifnet_lock;
129static if_com_alloc_t *if_com_alloc[256];
130static if_com_free_t *if_com_free[256];
131
132static int if_indexlim = 8;
133static struct knlist ifklist;
134
135static void filt_netdetach(struct knote *kn);

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

277 */
278/* ARGSUSED*/
279static void
280if_init(void *dummy __unused)
281{
282
283 IFNET_LOCK_INIT();
284 TAILQ_INIT(&ifnet);
131struct mtx ifnet_lock;
132static if_com_alloc_t *if_com_alloc[256];
133static if_com_free_t *if_com_free[256];
134
135static int if_indexlim = 8;
136static struct knlist ifklist;
137
138static void filt_netdetach(struct knote *kn);

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

280 */
281/* ARGSUSED*/
282static void
283if_init(void *dummy __unused)
284{
285
286 IFNET_LOCK_INIT();
287 TAILQ_INIT(&ifnet);
288 TAILQ_INIT(&ifg_head);
285 knlist_init(&ifklist, NULL, NULL, NULL, NULL);
286 if_grow(); /* create initial table */
287 ifdev_byindex(0) = make_dev(&net_cdevsw, 0,
288 UID_ROOT, GID_WHEEL, 0600, "network");
289 if_clone_init();
290}
291
292static void

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

436 * The old code would work if the interface passed a pre-existing
437 * chain of ifaddrs to this code. We don't trust our callers to
438 * properly initialize the tailq, however, so we no longer allow
439 * this unlikely case.
440 */
441 TAILQ_INIT(&ifp->if_addrhead);
442 TAILQ_INIT(&ifp->if_prefixhead);
443 TAILQ_INIT(&ifp->if_multiaddrs);
289 knlist_init(&ifklist, NULL, NULL, NULL, NULL);
290 if_grow(); /* create initial table */
291 ifdev_byindex(0) = make_dev(&net_cdevsw, 0,
292 UID_ROOT, GID_WHEEL, 0600, "network");
293 if_clone_init();
294}
295
296static void

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

440 * The old code would work if the interface passed a pre-existing
441 * chain of ifaddrs to this code. We don't trust our callers to
442 * properly initialize the tailq, however, so we no longer allow
443 * this unlikely case.
444 */
445 TAILQ_INIT(&ifp->if_addrhead);
446 TAILQ_INIT(&ifp->if_prefixhead);
447 TAILQ_INIT(&ifp->if_multiaddrs);
448 TAILQ_INIT(&ifp->if_groups);
449
450 if_addgroup(ifp, IFG_ALL);
451
444 knlist_init(&ifp->if_klist, NULL, NULL, NULL, NULL);
445 getmicrotime(&ifp->if_lastchange);
446 ifp->if_data.ifi_epoch = time_uptime;
447 ifp->if_data.ifi_datalen = sizeof(struct if_data);
448
449#ifdef MAC
450 mac_init_ifnet(ifp);
451 mac_create_ifnet(ifp);

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

710 TAILQ_REMOVE(&ifnet, ifp, if_link);
711 IFNET_WUNLOCK();
712 mtx_destroy(&ifp->if_snd.ifq_mtx);
713 IF_AFDATA_DESTROY(ifp);
714 splx(s);
715}
716
717/*
452 knlist_init(&ifp->if_klist, NULL, NULL, NULL, NULL);
453 getmicrotime(&ifp->if_lastchange);
454 ifp->if_data.ifi_epoch = time_uptime;
455 ifp->if_data.ifi_datalen = sizeof(struct if_data);
456
457#ifdef MAC
458 mac_init_ifnet(ifp);
459 mac_create_ifnet(ifp);

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

718 TAILQ_REMOVE(&ifnet, ifp, if_link);
719 IFNET_WUNLOCK();
720 mtx_destroy(&ifp->if_snd.ifq_mtx);
721 IF_AFDATA_DESTROY(ifp);
722 splx(s);
723}
724
725/*
726 * Add a group to an interface
727 */
728int
729if_addgroup(struct ifnet *ifp, const char *groupname)
730{
731 struct ifg_list *ifgl;
732 struct ifg_group *ifg = NULL;
733 struct ifg_member *ifgm;
734
735 if (groupname[0] && groupname[strlen(groupname) - 1] >= '0' &&
736 groupname[strlen(groupname) - 1] <= '9')
737 return (EINVAL);
738
739 IFNET_WLOCK();
740 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
741 if (!strcmp(ifgl->ifgl_group->ifg_group, groupname)) {
742 IFNET_WUNLOCK();
743 return (EEXIST);
744 }
745
746 if ((ifgl = (struct ifg_list *)malloc(sizeof(struct ifg_list), M_TEMP,
747 M_NOWAIT)) == NULL) {
748 IFNET_WUNLOCK();
749 return (ENOMEM);
750 }
751
752 if ((ifgm = (struct ifg_member *)malloc(sizeof(struct ifg_member),
753 M_TEMP, M_NOWAIT)) == NULL) {
754 free(ifgl, M_TEMP);
755 IFNET_WUNLOCK();
756 return (ENOMEM);
757 }
758
759 TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
760 if (!strcmp(ifg->ifg_group, groupname))
761 break;
762
763 if (ifg == NULL) {
764 if ((ifg = (struct ifg_group *)malloc(sizeof(struct ifg_group),
765 M_TEMP, M_NOWAIT)) == NULL) {
766 free(ifgl, M_TEMP);
767 free(ifgm, M_TEMP);
768 IFNET_WUNLOCK();
769 return (ENOMEM);
770 }
771 strlcpy(ifg->ifg_group, groupname, sizeof(ifg->ifg_group));
772 ifg->ifg_refcnt = 0;
773 TAILQ_INIT(&ifg->ifg_members);
774 EVENTHANDLER_INVOKE(group_attach_event, ifg);
775 TAILQ_INSERT_TAIL(&ifg_head, ifg, ifg_next);
776 }
777
778 ifg->ifg_refcnt++;
779 ifgl->ifgl_group = ifg;
780 ifgm->ifgm_ifp = ifp;
781
782 IF_ADDR_LOCK(ifp);
783 TAILQ_INSERT_TAIL(&ifg->ifg_members, ifgm, ifgm_next);
784 TAILQ_INSERT_TAIL(&ifp->if_groups, ifgl, ifgl_next);
785 IF_ADDR_UNLOCK(ifp);
786
787 IFNET_WUNLOCK();
788
789 EVENTHANDLER_INVOKE(group_change_event, groupname);
790
791 return (0);
792}
793
794/*
795 * Remove a group from an interface
796 */
797int
798if_delgroup(struct ifnet *ifp, const char *groupname)
799{
800 struct ifg_list *ifgl;
801 struct ifg_member *ifgm;
802
803 IFNET_WLOCK();
804 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
805 if (!strcmp(ifgl->ifgl_group->ifg_group, groupname))
806 break;
807 if (ifgl == NULL) {
808 IFNET_WUNLOCK();
809 return (ENOENT);
810 }
811
812 IF_ADDR_LOCK(ifp);
813 TAILQ_REMOVE(&ifp->if_groups, ifgl, ifgl_next);
814 IF_ADDR_UNLOCK(ifp);
815
816 TAILQ_FOREACH(ifgm, &ifgl->ifgl_group->ifg_members, ifgm_next)
817 if (ifgm->ifgm_ifp == ifp)
818 break;
819
820 if (ifgm != NULL) {
821 TAILQ_REMOVE(&ifgl->ifgl_group->ifg_members, ifgm, ifgm_next);
822 free(ifgm, M_TEMP);
823 }
824
825 if (--ifgl->ifgl_group->ifg_refcnt == 0) {
826 TAILQ_REMOVE(&ifg_head, ifgl->ifgl_group, ifg_next);
827 EVENTHANDLER_INVOKE(group_detach_event, ifgl->ifgl_group);
828 free(ifgl->ifgl_group, M_TEMP);
829 }
830 IFNET_WUNLOCK();
831
832 free(ifgl, M_TEMP);
833
834 EVENTHANDLER_INVOKE(group_change_event, groupname);
835
836 return (0);
837}
838
839/*
840 * Stores all groups from an interface in memory pointed
841 * to by data
842 */
843static int
844if_getgroup(struct ifgroupreq *data, struct ifnet *ifp)
845{
846 int len, error;
847 struct ifg_list *ifgl;
848 struct ifg_req ifgrq, *ifgp;
849 struct ifgroupreq *ifgr = data;
850
851 if (ifgr->ifgr_len == 0) {
852 IF_ADDR_LOCK(ifp);
853 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
854 ifgr->ifgr_len += sizeof(struct ifg_req);
855 IF_ADDR_UNLOCK(ifp);
856 return (0);
857 }
858
859 len = ifgr->ifgr_len;
860 ifgp = ifgr->ifgr_groups;
861 /* XXX: wire */
862 IF_ADDR_LOCK(ifp);
863 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) {
864 if (len < sizeof(ifgrq)) {
865 IF_ADDR_UNLOCK(ifp);
866 return (EINVAL);
867 }
868 bzero(&ifgrq, sizeof ifgrq);
869 strlcpy(ifgrq.ifgrq_group, ifgl->ifgl_group->ifg_group,
870 sizeof(ifgrq.ifgrq_group));
871 if ((error = copyout(&ifgrq, ifgp, sizeof(struct ifg_req)))) {
872 IF_ADDR_UNLOCK(ifp);
873 return (error);
874 }
875 len -= sizeof(ifgrq);
876 ifgp++;
877 }
878 IF_ADDR_UNLOCK(ifp);
879
880 return (0);
881}
882
883/*
884 * Stores all members of a group in memory pointed to by data
885 */
886static int
887if_getgroupmembers(struct ifgroupreq *data)
888{
889 struct ifgroupreq *ifgr = data;
890 struct ifg_group *ifg;
891 struct ifg_member *ifgm;
892 struct ifg_req ifgrq, *ifgp;
893 int len, error;
894
895 IFNET_RLOCK();
896 TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
897 if (!strcmp(ifg->ifg_group, ifgr->ifgr_name))
898 break;
899 if (ifg == NULL) {
900 IFNET_RUNLOCK();
901 return (ENOENT);
902 }
903
904 if (ifgr->ifgr_len == 0) {
905 TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next)
906 ifgr->ifgr_len += sizeof(ifgrq);
907 IFNET_RUNLOCK();
908 return (0);
909 }
910
911 len = ifgr->ifgr_len;
912 ifgp = ifgr->ifgr_groups;
913 TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) {
914 if (len < sizeof(ifgrq)) {
915 IFNET_RUNLOCK();
916 return (EINVAL);
917 }
918 bzero(&ifgrq, sizeof ifgrq);
919 strlcpy(ifgrq.ifgrq_member, ifgm->ifgm_ifp->if_xname,
920 sizeof(ifgrq.ifgrq_member));
921 if ((error = copyout(&ifgrq, ifgp, sizeof(struct ifg_req)))) {
922 IFNET_RUNLOCK();
923 return (error);
924 }
925 len -= sizeof(ifgrq);
926 ifgp++;
927 }
928 IFNET_RUNLOCK();
929
930 return (0);
931}
932
933/*
718 * Delete Routes for a Network Interface
719 *
720 * Called for each routing entry via the rnh->rnh_walktree() call above
721 * to delete all route entries referencing a detaching network interface.
722 *
723 * Arguments:
724 * rn pointer to node in the routing table
725 * arg argument passed to rnh->rnh_walktree() - detaching interface

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

1467 case SIOCSIFLLADDR:
1468 error = suser(td);
1469 if (error)
1470 return (error);
1471 error = if_setlladdr(ifp,
1472 ifr->ifr_addr.sa_data, ifr->ifr_addr.sa_len);
1473 break;
1474
934 * Delete Routes for a Network Interface
935 *
936 * Called for each routing entry via the rnh->rnh_walktree() call above
937 * to delete all route entries referencing a detaching network interface.
938 *
939 * Arguments:
940 * rn pointer to node in the routing table
941 * arg argument passed to rnh->rnh_walktree() - detaching interface

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

1683 case SIOCSIFLLADDR:
1684 error = suser(td);
1685 if (error)
1686 return (error);
1687 error = if_setlladdr(ifp,
1688 ifr->ifr_addr.sa_data, ifr->ifr_addr.sa_len);
1689 break;
1690
1691 case SIOCAIFGROUP:
1692 {
1693 struct ifgroupreq *ifgr = (struct ifgroupreq *)ifr;
1694
1695 error = suser(td);
1696 if (error)
1697 return (error);
1698 if ((error = if_addgroup(ifp, ifgr->ifgr_group)))
1699 return (error);
1700 break;
1701 }
1702
1703 case SIOCGIFGROUP:
1704 if ((error = if_getgroup((struct ifgroupreq *)ifr, ifp)))
1705 return (error);
1706 break;
1707
1708 case SIOCDIFGROUP:
1709 {
1710 struct ifgroupreq *ifgr = (struct ifgroupreq *)ifr;
1711
1712 error = suser(td);
1713 if (error)
1714 return (error);
1715 if ((error = if_delgroup(ifp, ifgr->ifgr_group)))
1716 return (error);
1717 break;
1718 }
1719
1475 default:
1476 error = ENOIOCTL;
1477 break;
1478 }
1479 return (error);
1480}
1481
1482/*

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

1506 if ((error = suser(td)) != 0)
1507 return (error);
1508 return ((cmd == SIOCIFCREATE) ?
1509 if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name)) :
1510 if_clone_destroy(ifr->ifr_name));
1511
1512 case SIOCIFGCLONERS:
1513 return (if_clone_list((struct if_clonereq *)data));
1720 default:
1721 error = ENOIOCTL;
1722 break;
1723 }
1724 return (error);
1725}
1726
1727/*

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

1751 if ((error = suser(td)) != 0)
1752 return (error);
1753 return ((cmd == SIOCIFCREATE) ?
1754 if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name)) :
1755 if_clone_destroy(ifr->ifr_name));
1756
1757 case SIOCIFGCLONERS:
1758 return (if_clone_list((struct if_clonereq *)data));
1759 case SIOCGIFGMEMB:
1760 return (if_getgroupmembers((struct ifgroupreq *)data));
1514 }
1515
1516 ifp = ifunit(ifr->ifr_name);
1517 if (ifp == 0)
1518 return (ENXIO);
1519
1520 error = ifhwioctl(cmd, ifp, data, td);
1521 if (error != ENOIOCTL)

--- 767 unchanged lines hidden ---
1761 }
1762
1763 ifp = ifunit(ifr->ifr_name);
1764 if (ifp == 0)
1765 return (ENXIO);
1766
1767 error = ifhwioctl(cmd, ifp, data, td);
1768 if (error != ENOIOCTL)

--- 767 unchanged lines hidden ---