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 --- |