if_ether.c (227790) | if_ether.c (228571) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986, 1988, 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 --- 22 unchanged lines hidden (view full) --- 31 32/* 33 * Ethernet address resolution protocol. 34 * TODO: 35 * add "inuse/lock" bit (or ref. count) along with valid bit 36 */ 37 38#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1982, 1986, 1988, 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 --- 22 unchanged lines hidden (view full) --- 31 32/* 33 * Ethernet address resolution protocol. 34 * TODO: 35 * add "inuse/lock" bit (or ref. count) along with valid bit 36 */ 37 38#include <sys/cdefs.h> |
39__FBSDID("$FreeBSD: head/sys/netinet/if_ether.c 227790 2011-11-21 13:40:35Z glebius $"); | 39__FBSDID("$FreeBSD: head/sys/netinet/if_ether.c 228571 2011-12-16 12:16:56Z glebius $"); |
40 41#include "opt_inet.h" 42 43#include <sys/param.h> 44#include <sys/kernel.h> 45#include <sys/queue.h> 46#include <sys/sysctl.h> 47#include <sys/systm.h> --- 86 unchanged lines hidden (view full) --- 134static const struct netisr_handler arp_nh = { 135 .nh_name = "arp", 136 .nh_handler = arpintr, 137 .nh_proto = NETISR_ARP, 138 .nh_policy = NETISR_POLICY_SOURCE, 139}; 140 141#ifdef AF_INET | 40 41#include "opt_inet.h" 42 43#include <sys/param.h> 44#include <sys/kernel.h> 45#include <sys/queue.h> 46#include <sys/sysctl.h> 47#include <sys/systm.h> --- 86 unchanged lines hidden (view full) --- 134static const struct netisr_handler arp_nh = { 135 .nh_name = "arp", 136 .nh_handler = arpintr, 137 .nh_proto = NETISR_ARP, 138 .nh_policy = NETISR_POLICY_SOURCE, 139}; 140 141#ifdef AF_INET |
142void arp_ifscrub(struct ifnet *ifp, uint32_t addr); 143 | |
144/* 145 * called by in_ifscrub to remove entry from the table when 146 * the interface goes away 147 */ 148void 149arp_ifscrub(struct ifnet *ifp, uint32_t addr) 150{ 151 struct sockaddr_in addr4; --- 359 unchanged lines hidden (view full) --- 511 struct ifaddr *ifa; 512 struct in_ifaddr *ia; 513 struct sockaddr sa; 514 struct in_addr isaddr, itaddr, myaddr; 515 u_int8_t *enaddr = NULL; 516 int op, flags; 517 int req_len; 518 int bridged = 0, is_bridge = 0; | 142/* 143 * called by in_ifscrub to remove entry from the table when 144 * the interface goes away 145 */ 146void 147arp_ifscrub(struct ifnet *ifp, uint32_t addr) 148{ 149 struct sockaddr_in addr4; --- 359 unchanged lines hidden (view full) --- 509 struct ifaddr *ifa; 510 struct in_ifaddr *ia; 511 struct sockaddr sa; 512 struct in_addr isaddr, itaddr, myaddr; 513 u_int8_t *enaddr = NULL; 514 int op, flags; 515 int req_len; 516 int bridged = 0, is_bridge = 0; |
519 int carp_match = 0; | 517 int carped; |
520 struct sockaddr_in sin; 521 sin.sin_len = sizeof(struct sockaddr_in); 522 sin.sin_family = AF_INET; 523 sin.sin_addr.s_addr = 0; 524 525 if (ifp->if_bridge) 526 bridged = 1; 527 if (ifp->if_type == IFT_BRIDGE) --- 28 unchanged lines hidden (view full) --- 556 557 if (op == ARPOP_REPLY) 558 ARPSTAT_INC(rxreplies); 559 560 /* 561 * For a bridge, we want to check the address irrespective 562 * of the receive interface. (This will change slightly 563 * when we have clusters of interfaces). | 518 struct sockaddr_in sin; 519 sin.sin_len = sizeof(struct sockaddr_in); 520 sin.sin_family = AF_INET; 521 sin.sin_addr.s_addr = 0; 522 523 if (ifp->if_bridge) 524 bridged = 1; 525 if (ifp->if_type == IFT_BRIDGE) --- 28 unchanged lines hidden (view full) --- 554 555 if (op == ARPOP_REPLY) 556 ARPSTAT_INC(rxreplies); 557 558 /* 559 * For a bridge, we want to check the address irrespective 560 * of the receive interface. (This will change slightly 561 * when we have clusters of interfaces). |
564 * If the interface does not match, but the recieving interface 565 * is part of carp, we call carp_iamatch to see if this is a 566 * request for the virtual host ip. 567 * XXX: This is really ugly! | |
568 */ 569 IN_IFADDR_RLOCK(); 570 LIST_FOREACH(ia, INADDR_HASH(itaddr.s_addr), ia_hash) { 571 if (((bridged && ia->ia_ifp->if_bridge == ifp->if_bridge) || 572 ia->ia_ifp == ifp) && | 562 */ 563 IN_IFADDR_RLOCK(); 564 LIST_FOREACH(ia, INADDR_HASH(itaddr.s_addr), ia_hash) { 565 if (((bridged && ia->ia_ifp->if_bridge == ifp->if_bridge) || 566 ia->ia_ifp == ifp) && |
573 itaddr.s_addr == ia->ia_addr.sin_addr.s_addr) { | 567 itaddr.s_addr == ia->ia_addr.sin_addr.s_addr && 568 (ia->ia_ifa.ifa_carp == NULL || 569 (*carp_iamatch_p)(&ia->ia_ifa, &enaddr))) { |
574 ifa_ref(&ia->ia_ifa); 575 IN_IFADDR_RUNLOCK(); 576 goto match; 577 } | 570 ifa_ref(&ia->ia_ifa); 571 IN_IFADDR_RUNLOCK(); 572 goto match; 573 } |
578 if (ifp->if_carp != NULL && 579 (*carp_iamatch_p)(ifp, ia, &isaddr, &enaddr) && 580 itaddr.s_addr == ia->ia_addr.sin_addr.s_addr) { 581 carp_match = 1; 582 ifa_ref(&ia->ia_ifa); 583 IN_IFADDR_RUNLOCK(); 584 goto match; 585 } | |
586 } 587 LIST_FOREACH(ia, INADDR_HASH(isaddr.s_addr), ia_hash) 588 if (((bridged && ia->ia_ifp->if_bridge == ifp->if_bridge) || 589 ia->ia_ifp == ifp) && 590 isaddr.s_addr == ia->ia_addr.sin_addr.s_addr) { 591 ifa_ref(&ia->ia_ifa); 592 IN_IFADDR_RUNLOCK(); 593 goto match; --- 44 unchanged lines hidden (view full) --- 638 IN_IFADDR_RUNLOCK(); 639 goto drop; 640 } 641 ifa_ref(&ia->ia_ifa); 642 IN_IFADDR_RUNLOCK(); 643match: 644 if (!enaddr) 645 enaddr = (u_int8_t *)IF_LLADDR(ifp); | 574 } 575 LIST_FOREACH(ia, INADDR_HASH(isaddr.s_addr), ia_hash) 576 if (((bridged && ia->ia_ifp->if_bridge == ifp->if_bridge) || 577 ia->ia_ifp == ifp) && 578 isaddr.s_addr == ia->ia_addr.sin_addr.s_addr) { 579 ifa_ref(&ia->ia_ifa); 580 IN_IFADDR_RUNLOCK(); 581 goto match; --- 44 unchanged lines hidden (view full) --- 626 IN_IFADDR_RUNLOCK(); 627 goto drop; 628 } 629 ifa_ref(&ia->ia_ifa); 630 IN_IFADDR_RUNLOCK(); 631match: 632 if (!enaddr) 633 enaddr = (u_int8_t *)IF_LLADDR(ifp); |
634 carped = (ia->ia_ifa.ifa_carp != NULL); |
|
646 myaddr = ia->ia_addr.sin_addr; 647 ifa_free(&ia->ia_ifa); 648 if (!bcmp(ar_sha(ah), enaddr, ifp->if_addrlen)) 649 goto drop; /* it's from me, ignore it. */ 650 if (!bcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen)) { 651 log(LOG_NOTICE, 652 "arp: link address is broadcast for IP address %s!\n", 653 inet_ntoa(isaddr)); 654 goto drop; 655 } 656 /* 657 * Warn if another host is using the same IP address, but only if the 658 * IP address isn't 0.0.0.0, which is used for DHCP only, in which 659 * case we suppress the warning to avoid false positive complaints of 660 * potential misconfiguration. 661 */ | 635 myaddr = ia->ia_addr.sin_addr; 636 ifa_free(&ia->ia_ifa); 637 if (!bcmp(ar_sha(ah), enaddr, ifp->if_addrlen)) 638 goto drop; /* it's from me, ignore it. */ 639 if (!bcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen)) { 640 log(LOG_NOTICE, 641 "arp: link address is broadcast for IP address %s!\n", 642 inet_ntoa(isaddr)); 643 goto drop; 644 } 645 /* 646 * Warn if another host is using the same IP address, but only if the 647 * IP address isn't 0.0.0.0, which is used for DHCP only, in which 648 * case we suppress the warning to avoid false positive complaints of 649 * potential misconfiguration. 650 */ |
662 if (!bridged && isaddr.s_addr == myaddr.s_addr && myaddr.s_addr != 0) { 663 log(LOG_ERR, 664 "arp: %*D is using my IP address %s on %s!\n", | 651 if (!bridged && !carped && isaddr.s_addr == myaddr.s_addr && 652 myaddr.s_addr != 0) { 653 log(LOG_ERR, "arp: %*D is using my IP address %s on %s!\n", |
665 ifp->if_addrlen, (u_char *)ar_sha(ah), ":", 666 inet_ntoa(isaddr), ifp->if_xname); 667 itaddr = myaddr; 668 ARPSTAT_INC(dupips); 669 goto reply; 670 } 671 if (ifp->if_flags & IFF_STATICARP) 672 goto reply; --- 4 unchanged lines hidden (view full) --- 677 sin.sin_addr = isaddr; 678 flags = (itaddr.s_addr == myaddr.s_addr) ? LLE_CREATE : 0; 679 flags |= LLE_EXCLUSIVE; 680 IF_AFDATA_LOCK(ifp); 681 la = lla_lookup(LLTABLE(ifp), flags, (struct sockaddr *)&sin); 682 IF_AFDATA_UNLOCK(ifp); 683 if (la != NULL) { 684 /* the following is not an error when doing bridging */ | 654 ifp->if_addrlen, (u_char *)ar_sha(ah), ":", 655 inet_ntoa(isaddr), ifp->if_xname); 656 itaddr = myaddr; 657 ARPSTAT_INC(dupips); 658 goto reply; 659 } 660 if (ifp->if_flags & IFF_STATICARP) 661 goto reply; --- 4 unchanged lines hidden (view full) --- 666 sin.sin_addr = isaddr; 667 flags = (itaddr.s_addr == myaddr.s_addr) ? LLE_CREATE : 0; 668 flags |= LLE_EXCLUSIVE; 669 IF_AFDATA_LOCK(ifp); 670 la = lla_lookup(LLTABLE(ifp), flags, (struct sockaddr *)&sin); 671 IF_AFDATA_UNLOCK(ifp); 672 if (la != NULL) { 673 /* the following is not an error when doing bridging */ |
685 if (!bridged && la->lle_tbl->llt_ifp != ifp && !carp_match) { | 674 if (!bridged && la->lle_tbl->llt_ifp != ifp) { |
686 if (log_arp_wrong_iface) 687 log(LOG_WARNING, "arp: %s is on %s " 688 "but got reply from %*D on %s\n", 689 inet_ntoa(isaddr), 690 la->lle_tbl->llt_ifp->if_xname, 691 ifp->if_addrlen, (u_char *)ar_sha(ah), ":", 692 ifp->if_xname); 693 LLE_WUNLOCK(la); --- 180 unchanged lines hidden (view full) --- 874} 875#endif 876 877void 878arp_ifinit(struct ifnet *ifp, struct ifaddr *ifa) 879{ 880 struct llentry *lle; 881 | 675 if (log_arp_wrong_iface) 676 log(LOG_WARNING, "arp: %s is on %s " 677 "but got reply from %*D on %s\n", 678 inet_ntoa(isaddr), 679 la->lle_tbl->llt_ifp->if_xname, 680 ifp->if_addrlen, (u_char *)ar_sha(ah), ":", 681 ifp->if_xname); 682 LLE_WUNLOCK(la); --- 180 unchanged lines hidden (view full) --- 863} 864#endif 865 866void 867arp_ifinit(struct ifnet *ifp, struct ifaddr *ifa) 868{ 869 struct llentry *lle; 870 |
871 if (ifa->ifa_carp != NULL) 872 return; 873 |
|
882 if (ntohl(IA_SIN(ifa)->sin_addr.s_addr) != INADDR_ANY) { 883 arprequest(ifp, &IA_SIN(ifa)->sin_addr, 884 &IA_SIN(ifa)->sin_addr, IF_LLADDR(ifp)); 885 /* 886 * interface address is considered static entry 887 * because the output of the arp utility shows 888 * that L2 entry as permanent 889 */ --- 29 unchanged lines hidden --- | 874 if (ntohl(IA_SIN(ifa)->sin_addr.s_addr) != INADDR_ANY) { 875 arprequest(ifp, &IA_SIN(ifa)->sin_addr, 876 &IA_SIN(ifa)->sin_addr, IF_LLADDR(ifp)); 877 /* 878 * interface address is considered static entry 879 * because the output of the arp utility shows 880 * that L2 entry as permanent 881 */ --- 29 unchanged lines hidden --- |