| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: if_llatbl.c,v 1.27 2018/06/05 01:25:59 nonaka Exp $ */ | | 1 | /* $NetBSD: if_llatbl.c,v 1.28 2018/07/10 01:23:13 ozaki-r Exp $ */ |
2 | /* | | 2 | /* |
3 | * Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved. | | 3 | * Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved. |
4 | * Copyright (c) 2004-2008 Qing Li. All rights reserved. | | 4 | * Copyright (c) 2004-2008 Qing Li. All rights reserved. |
5 | * Copyright (c) 2008 Kip Macy. All rights reserved. | | 5 | * Copyright (c) 2008 Kip Macy. All rights reserved. |
6 | * Copyright (c) 2015 The NetBSD Foundation, Inc. | | 6 | * Copyright (c) 2015 The NetBSD Foundation, Inc. |
7 | * All rights reserved. | | 7 | * All rights reserved. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| @@ -662,40 +662,50 @@ lla_rt_output(const u_char rtm_type, con | | | @@ -662,40 +662,50 @@ lla_rt_output(const u_char rtm_type, con |
662 | KASSERTMSG(llt != NULL, "Yep, ugly hacks are bad"); | | 662 | KASSERTMSG(llt != NULL, "Yep, ugly hacks are bad"); |
663 | | | 663 | |
664 | error = 0; | | 664 | error = 0; |
665 | | | 665 | |
666 | switch (rtm_type) { | | 666 | switch (rtm_type) { |
667 | case RTM_ADD: { | | 667 | case RTM_ADD: { |
668 | struct rtentry *rt; | | 668 | struct rtentry *rt; |
669 | | | 669 | |
670 | /* Never call rtalloc1 with IF_AFDATA_WLOCK */ | | 670 | /* Never call rtalloc1 with IF_AFDATA_WLOCK */ |
671 | rt = rtalloc1(dst, 0); | | 671 | rt = rtalloc1(dst, 0); |
672 | | | 672 | |
673 | /* Add static LLE */ | | 673 | /* Add static LLE */ |
674 | IF_AFDATA_WLOCK(ifp); | | 674 | IF_AFDATA_WLOCK(ifp); |
675 | lle = lla_lookup(llt, 0, dst); | | 675 | lle = lla_lookup(llt, LLE_EXCLUSIVE, dst); |
676 | | | 676 | |
677 | /* Cannot overwrite an existing static entry */ | | 677 | /* Cannot overwrite an existing static entry */ |
678 | if (lle != NULL && | | 678 | if (lle != NULL && |
679 | (lle->la_flags & LLE_STATIC || lle->la_expire == 0)) { | | 679 | (lle->la_flags & LLE_STATIC || lle->la_expire == 0)) { |
680 | LLE_RUNLOCK(lle); | | 680 | LLE_RUNLOCK(lle); |
681 | IF_AFDATA_WUNLOCK(ifp); | | 681 | IF_AFDATA_WUNLOCK(ifp); |
682 | if (rt != NULL) | | 682 | if (rt != NULL) |
683 | rt_unref(rt); | | 683 | rt_unref(rt); |
684 | error = EEXIST; | | 684 | error = EEXIST; |
685 | goto out; | | 685 | goto out; |
686 | } | | 686 | } |
687 | if (lle != NULL) | | 687 | |
688 | LLE_RUNLOCK(lle); | | 688 | /* |
| | | 689 | * We can't overwrite an existing entry to avoid race |
| | | 690 | * conditions so remove it first. |
| | | 691 | */ |
| | | 692 | if (lle != NULL) { |
| | | 693 | size_t pkts_dropped = llentry_free(lle); |
| | | 694 | if (dst->sa_family == AF_INET) { |
| | | 695 | arp_stat_add(ARP_STAT_DFRDROPPED, |
| | | 696 | (uint64_t)pkts_dropped); |
| | | 697 | } |
| | | 698 | } |
689 | | | 699 | |
690 | lle = lla_create(llt, 0, dst, rt); | | 700 | lle = lla_create(llt, 0, dst, rt); |
691 | if (lle == NULL) { | | 701 | if (lle == NULL) { |
692 | IF_AFDATA_WUNLOCK(ifp); | | 702 | IF_AFDATA_WUNLOCK(ifp); |
693 | if (rt != NULL) | | 703 | if (rt != NULL) |
694 | rt_unref(rt); | | 704 | rt_unref(rt); |
695 | error = ENOMEM; | | 705 | error = ENOMEM; |
696 | goto out; | | 706 | goto out; |
697 | } | | 707 | } |
698 | | | 708 | |
699 | KASSERT(ifp->if_addrlen <= sizeof(lle->ll_addr)); | | 709 | KASSERT(ifp->if_addrlen <= sizeof(lle->ll_addr)); |
700 | memcpy(&lle->ll_addr, CLLADDR(dl), ifp->if_addrlen); | | 710 | memcpy(&lle->ll_addr, CLLADDR(dl), ifp->if_addrlen); |
701 | if ((rtm_flags & RTF_ANNOUNCE)) | | 711 | if ((rtm_flags & RTF_ANNOUNCE)) |