Deleted Added
full compact
in.c (286955) in.c (287789)
1/*-
2 * Copyright (c) 1982, 1986, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (C) 2001 WIDE Project. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

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

26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * @(#)in.c 8.4 (Berkeley) 1/9/95
31 */
32
33#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1982, 1986, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (C) 2001 WIDE Project. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

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

26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * @(#)in.c 8.4 (Berkeley) 1/9/95
31 */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/netinet/in.c 286955 2015-08-20 12:05:17Z melifaro $");
34__FBSDID("$FreeBSD: head/sys/netinet/in.c 287789 2015-09-14 16:48:19Z melifaro $");
35
36#include "opt_mpath.h"
37
38#include <sys/param.h>
39#include <sys/eventhandler.h>
40#include <sys/systm.h>
41#include <sys/sockio.h>
42#include <sys/malloc.h>

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

719 */
720 error = rtinit(&target->ia_ifa, (int)RTM_ADD, flags);
721 if (!error)
722 target->ia_flags |= IFA_ROUTE;
723 return (error);
724}
725
726/*
35
36#include "opt_mpath.h"
37
38#include <sys/param.h>
39#include <sys/eventhandler.h>
40#include <sys/systm.h>
41#include <sys/sockio.h>
42#include <sys/malloc.h>

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

719 */
720 error = rtinit(&target->ia_ifa, (int)RTM_ADD, flags);
721 if (!error)
722 target->ia_flags |= IFA_ROUTE;
723 return (error);
724}
725
726/*
727 * Removes either all lle entries for given @ia, or lle
728 * corresponding to @ia address.
729 */
730static void
731in_scrubprefixlle(struct in_ifaddr *ia, int all, u_int flags)
732{
733 struct sockaddr_in addr, mask;
734 struct sockaddr *saddr, *smask;
735 struct ifnet *ifp;
736
737 /*
738 * remove all L2 entries on the given prefix
739 */
740 saddr = (struct sockaddr *)&addr;
741 bzero(&addr, sizeof(addr));
742 addr.sin_len = sizeof(addr);
743 addr.sin_family = AF_INET;
744 addr.sin_addr.s_addr = ntohl(ia->ia_addr.sin_addr.s_addr);
745 smask = (struct sockaddr *)&mask;
746 bzero(&mask, sizeof(mask));
747 mask.sin_len = sizeof(mask);
748 mask.sin_family = AF_INET;
749 mask.sin_addr.s_addr = ia->ia_subnetmask;
750 ifp = ia->ia_ifp;
751
752 if (all)
753 lltable_prefix_free(AF_INET, saddr, smask, flags);
754 else
755 lltable_delete_addr(LLTABLE(ifp), LLE_IFADDR, saddr);
756}
757
758/*
727 * If there is no other address in the system that can serve a route to the
728 * same prefix, remove the route. Hand over the route to the new address
729 * otherwise.
730 */
731int
732in_scrubprefix(struct in_ifaddr *target, u_int flags)
733{
734 struct rm_priotracker in_ifa_tracker;
735 struct in_ifaddr *ia;
736 struct in_addr prefix, mask, p, m;
737 int error = 0;
759 * If there is no other address in the system that can serve a route to the
760 * same prefix, remove the route. Hand over the route to the new address
761 * otherwise.
762 */
763int
764in_scrubprefix(struct in_ifaddr *target, u_int flags)
765{
766 struct rm_priotracker in_ifa_tracker;
767 struct in_ifaddr *ia;
768 struct in_addr prefix, mask, p, m;
769 int error = 0;
738 struct sockaddr_in prefix0, mask0;
739
740 /*
741 * Remove the loopback route to the interface address.
742 */
743 if ((target->ia_addr.sin_addr.s_addr != INADDR_ANY) &&
744 !(target->ia_ifp->if_flags & IFF_LOOPBACK) &&
745 (flags & LLE_STATIC)) {
746 struct in_ifaddr *eia;

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

752
753 error = ifa_switch_loopback_route((struct ifaddr *)eia,
754 (struct sockaddr *)&target->ia_addr, fibnum);
755 ifa_free(&eia->ia_ifa);
756 } else {
757 error = ifa_del_loopback_route((struct ifaddr *)target,
758 (struct sockaddr *)&target->ia_addr);
759 }
770
771 /*
772 * Remove the loopback route to the interface address.
773 */
774 if ((target->ia_addr.sin_addr.s_addr != INADDR_ANY) &&
775 !(target->ia_ifp->if_flags & IFF_LOOPBACK) &&
776 (flags & LLE_STATIC)) {
777 struct in_ifaddr *eia;

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

783
784 error = ifa_switch_loopback_route((struct ifaddr *)eia,
785 (struct sockaddr *)&target->ia_addr, fibnum);
786 ifa_free(&eia->ia_ifa);
787 } else {
788 error = ifa_del_loopback_route((struct ifaddr *)target,
789 (struct sockaddr *)&target->ia_addr);
790 }
760
761 if (!(target->ia_ifp->if_flags & IFF_NOARP))
762 /* remove arp cache */
763 arp_ifscrub(target->ia_ifp,
764 IA_SIN(target)->sin_addr.s_addr);
765 }
766
767 if (rtinitflags(target)) {
768 prefix = target->ia_dstaddr.sin_addr;
769 mask.s_addr = 0;
770 } else {
771 prefix = target->ia_addr.sin_addr;
772 mask = target->ia_sockmask.sin_addr;

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

812 IN_IFADDR_RUNLOCK(&in_ifa_tracker);
813 error = rtinit(&(target->ia_ifa), (int)RTM_DELETE,
814 rtinitflags(target));
815 if (error == 0)
816 target->ia_flags &= ~IFA_ROUTE;
817 else
818 log(LOG_INFO, "in_scrubprefix: err=%d, old prefix delete failed\n",
819 error);
791 }
792
793 if (rtinitflags(target)) {
794 prefix = target->ia_dstaddr.sin_addr;
795 mask.s_addr = 0;
796 } else {
797 prefix = target->ia_addr.sin_addr;
798 mask = target->ia_sockmask.sin_addr;

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

838 IN_IFADDR_RUNLOCK(&in_ifa_tracker);
839 error = rtinit(&(target->ia_ifa), (int)RTM_DELETE,
840 rtinitflags(target));
841 if (error == 0)
842 target->ia_flags &= ~IFA_ROUTE;
843 else
844 log(LOG_INFO, "in_scrubprefix: err=%d, old prefix delete failed\n",
845 error);
846 /* Scrub all entries IFF interface is different */
847 in_scrubprefixlle(target, target->ia_ifp != ia->ia_ifp,
848 flags);
820 error = rtinit(&ia->ia_ifa, (int)RTM_ADD,
821 rtinitflags(ia) | RTF_UP);
822 if (error == 0)
823 ia->ia_flags |= IFA_ROUTE;
824 else
825 log(LOG_INFO, "in_scrubprefix: err=%d, new prefix add failed\n",
826 error);
827 ifa_free(&ia->ia_ifa);
828 return (error);
829 }
830 }
831 IN_IFADDR_RUNLOCK(&in_ifa_tracker);
832
833 /*
834 * remove all L2 entries on the given prefix
835 */
849 error = rtinit(&ia->ia_ifa, (int)RTM_ADD,
850 rtinitflags(ia) | RTF_UP);
851 if (error == 0)
852 ia->ia_flags |= IFA_ROUTE;
853 else
854 log(LOG_INFO, "in_scrubprefix: err=%d, new prefix add failed\n",
855 error);
856 ifa_free(&ia->ia_ifa);
857 return (error);
858 }
859 }
860 IN_IFADDR_RUNLOCK(&in_ifa_tracker);
861
862 /*
863 * remove all L2 entries on the given prefix
864 */
836 bzero(&prefix0, sizeof(prefix0));
837 prefix0.sin_len = sizeof(prefix0);
838 prefix0.sin_family = AF_INET;
839 prefix0.sin_addr.s_addr = target->ia_subnet;
840 bzero(&mask0, sizeof(mask0));
841 mask0.sin_len = sizeof(mask0);
842 mask0.sin_family = AF_INET;
843 mask0.sin_addr.s_addr = target->ia_subnetmask;
844 lltable_prefix_free(AF_INET, (struct sockaddr *)&prefix0,
845 (struct sockaddr *)&mask0, flags);
865 in_scrubprefixlle(target, 1, flags);
846
847 /*
848 * As no-one seem to have this prefix, we can remove the route.
849 */
850 error = rtinit(&(target->ia_ifa), (int)RTM_DELETE, rtinitflags(target));
851 if (error == 0)
852 target->ia_flags &= ~IFA_ROUTE;
853 else

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

996 lle->base.lle_refcnt = 1;
997 lle->base.lle_free = in_lltable_destroy_lle;
998 LLE_LOCK_INIT(&lle->base);
999 callout_init(&lle->base.lle_timer, 1);
1000
1001 return (&lle->base);
1002}
1003
866
867 /*
868 * As no-one seem to have this prefix, we can remove the route.
869 */
870 error = rtinit(&(target->ia_ifa), (int)RTM_DELETE, rtinitflags(target));
871 if (error == 0)
872 target->ia_flags &= ~IFA_ROUTE;
873 else

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

1016 lle->base.lle_refcnt = 1;
1017 lle->base.lle_free = in_lltable_destroy_lle;
1018 LLE_LOCK_INIT(&lle->base);
1019 callout_init(&lle->base.lle_timer, 1);
1020
1021 return (&lle->base);
1022}
1023
1004#define IN_ARE_MASKED_ADDR_EQUAL(d, a, m) ( \
1005 (((ntohl((d).s_addr) ^ (a)->sin_addr.s_addr) & (m)->sin_addr.s_addr)) == 0 )
1024#define IN_ARE_MASKED_ADDR_EQUAL(d, a, m) ( \
1025 ((((d).s_addr ^ (a).s_addr) & (m).s_addr)) == 0 )
1006
1007static int
1026
1027static int
1008in_lltable_match_prefix(const struct sockaddr *prefix,
1009 const struct sockaddr *mask, u_int flags, struct llentry *lle)
1028in_lltable_match_prefix(const struct sockaddr *saddr,
1029 const struct sockaddr *smask, u_int flags, struct llentry *lle)
1010{
1030{
1011 const struct sockaddr_in *pfx = (const struct sockaddr_in *)prefix;
1012 const struct sockaddr_in *msk = (const struct sockaddr_in *)mask;
1031 struct in_addr addr, mask, lle_addr;
1013
1032
1014 /*
1015 * (flags & LLE_STATIC) means deleting all entries
1016 * including static ARP entries.
1017 */
1018 if (IN_ARE_MASKED_ADDR_EQUAL(lle->r_l3addr.addr4, pfx, msk) &&
1019 ((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC)))
1033 addr = ((const struct sockaddr_in *)saddr)->sin_addr;
1034 mask = ((const struct sockaddr_in *)smask)->sin_addr;
1035 lle_addr.s_addr = ntohl(lle->r_l3addr.addr4.s_addr);
1036
1037 if (IN_ARE_MASKED_ADDR_EQUAL(lle_addr, addr, mask) == 0)
1038 return (0);
1039
1040 if (lle->la_flags & LLE_IFADDR) {
1041
1042 /*
1043 * Delete LLE_IFADDR records IFF address & flag matches.
1044 * Note that addr is the interface address within prefix
1045 * being matched.
1046 * Note also we should handle 'ifdown' cases without removing
1047 * ifaddr macs.
1048 */
1049 if (addr.s_addr == lle_addr.s_addr && (flags & LLE_STATIC) != 0)
1050 return (1);
1051 return (0);
1052 }
1053
1054 /* flags & LLE_STATIC means deleting both dynamic and static entries */
1055 if ((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC))
1020 return (1);
1021
1022 return (0);
1023}
1024
1025static void
1026in_lltable_free_entry(struct lltable *llt, struct llentry *lle)
1027{

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

1161 continue;
1162 if (lle->r_l3addr.addr4.s_addr == dst.s_addr)
1163 break;
1164 }
1165
1166 return (lle);
1167}
1168
1056 return (1);
1057
1058 return (0);
1059}
1060
1061static void
1062in_lltable_free_entry(struct lltable *llt, struct llentry *lle)
1063{

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

1197 continue;
1198 if (lle->r_l3addr.addr4.s_addr == dst.s_addr)
1199 break;
1200 }
1201
1202 return (lle);
1203}
1204
1169static int
1170in_lltable_delete(struct lltable *llt, u_int flags,
1171 const struct sockaddr *l3addr)
1205static void
1206in_lltable_delete_entry(struct lltable *llt, struct llentry *lle)
1172{
1207{
1173 const struct sockaddr_in *sin = (const struct sockaddr_in *)l3addr;
1174 struct llentry *lle;
1175
1208
1176 IF_AFDATA_WLOCK_ASSERT(llt->llt_ifp);
1177 KASSERT(l3addr->sa_family == AF_INET,
1178 ("sin_family %d", l3addr->sa_family));
1179
1180 lle = in_lltable_find_dst(llt, sin->sin_addr);
1181 if (lle == NULL) {
1209 lle->la_flags |= LLE_DELETED;
1210 EVENTHANDLER_INVOKE(lle_event, lle, LLENTRY_DELETED);
1182#ifdef DIAGNOSTIC
1211#ifdef DIAGNOSTIC
1183 log(LOG_INFO, "interface address is missing from cache = %p in delete\n", lle);
1212 log(LOG_INFO, "ifaddr cache = %p is deleted\n", lle);
1184#endif
1213#endif
1185 return (ENOENT);
1186 }
1187
1188 if (!(lle->la_flags & LLE_IFADDR) || (flags & LLE_IFADDR)) {
1189 LLE_WLOCK(lle);
1190 lle->la_flags |= LLE_DELETED;
1191 EVENTHANDLER_INVOKE(lle_event, lle, LLENTRY_DELETED);
1192#ifdef DIAGNOSTIC
1193 log(LOG_INFO, "ifaddr cache = %p is deleted\n", lle);
1194#endif
1195 if ((lle->la_flags & (LLE_STATIC | LLE_IFADDR)) == LLE_STATIC)
1196 llentry_free(lle);
1197 else
1198 LLE_WUNLOCK(lle);
1199 }
1200
1201 return (0);
1214 llentry_free(lle);
1202}
1203
1204static struct llentry *
1205in_lltable_alloc(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
1206{
1207 const struct sockaddr_in *sin = (const struct sockaddr_in *)l3addr;
1208 struct ifnet *ifp = llt->llt_ifp;
1209 struct llentry *lle;

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

1329 struct lltable *llt;
1330
1331 llt = lltable_allocate_htbl(IN_LLTBL_DEFAULT_HSIZE);
1332 llt->llt_af = AF_INET;
1333 llt->llt_ifp = ifp;
1334
1335 llt->llt_lookup = in_lltable_lookup;
1336 llt->llt_alloc_entry = in_lltable_alloc;
1215}
1216
1217static struct llentry *
1218in_lltable_alloc(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
1219{
1220 const struct sockaddr_in *sin = (const struct sockaddr_in *)l3addr;
1221 struct ifnet *ifp = llt->llt_ifp;
1222 struct llentry *lle;

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

1342 struct lltable *llt;
1343
1344 llt = lltable_allocate_htbl(IN_LLTBL_DEFAULT_HSIZE);
1345 llt->llt_af = AF_INET;
1346 llt->llt_ifp = ifp;
1347
1348 llt->llt_lookup = in_lltable_lookup;
1349 llt->llt_alloc_entry = in_lltable_alloc;
1337 llt->llt_delete = in_lltable_delete;
1350 llt->llt_delete_entry = in_lltable_delete_entry;
1338 llt->llt_dump_entry = in_lltable_dump_entry;
1339 llt->llt_hash = in_lltable_hash;
1340 llt->llt_fill_sa_entry = in_lltable_fill_sa_entry;
1341 llt->llt_free_entry = in_lltable_free_entry;
1342 llt->llt_match_prefix = in_lltable_match_prefix;
1343 lltable_link(llt);
1344
1345 return (llt);

--- 24 unchanged lines hidden ---
1351 llt->llt_dump_entry = in_lltable_dump_entry;
1352 llt->llt_hash = in_lltable_hash;
1353 llt->llt_fill_sa_entry = in_lltable_fill_sa_entry;
1354 llt->llt_free_entry = in_lltable_free_entry;
1355 llt->llt_match_prefix = in_lltable_match_prefix;
1356 lltable_link(llt);
1357
1358 return (llt);

--- 24 unchanged lines hidden ---