diff options
author | Mike Rapoport <mike.rapoport@ravellosystems.com> | 2013-06-25 09:01:53 -0400 |
---|---|---|
committer | Stephen Hemminger <stephen@networkplumber.org> | 2013-06-25 12:31:37 -0400 |
commit | f0b074be7b61a800e39053d73dabf850649c1c8f (patch) | |
tree | 90d7cf0eeee6499e29a1abeeafbc5aaffbf42665 /drivers/net/vxlan.c | |
parent | a5e7c10a7ec244f272703f36f339c967efe1fc0d (diff) |
vxlan: introduce vxlan_fdb_parse
which will be reused by vxlan_fdb_delete
Signed-off-by: Mike Rapoport <mike.rapoport@ravellosystems.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Diffstat (limited to 'drivers/net/vxlan.c')
-rw-r--r-- | drivers/net/vxlan.c | 81 |
1 files changed, 50 insertions, 31 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 306bd94efa89..ee7cc71e57fd 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -518,58 +518,77 @@ static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f) | |||
518 | call_rcu(&f->rcu, vxlan_fdb_free); | 518 | call_rcu(&f->rcu, vxlan_fdb_free); |
519 | } | 519 | } |
520 | 520 | ||
521 | /* Add static entry (via netlink) */ | 521 | static int vxlan_fdb_parse(struct nlattr *tb[], struct vxlan_dev *vxlan, |
522 | static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], | 522 | __be32 *ip, __be16 *port, u32 *vni, u32 *ifindex) |
523 | struct net_device *dev, | ||
524 | const unsigned char *addr, u16 flags) | ||
525 | { | 523 | { |
526 | struct vxlan_dev *vxlan = netdev_priv(dev); | ||
527 | struct net *net = dev_net(vxlan->dev); | 524 | struct net *net = dev_net(vxlan->dev); |
528 | __be32 ip; | ||
529 | __be16 port; | ||
530 | u32 vni, ifindex; | ||
531 | int err; | ||
532 | |||
533 | if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_REACHABLE))) { | ||
534 | pr_info("RTM_NEWNEIGH with invalid state %#x\n", | ||
535 | ndm->ndm_state); | ||
536 | return -EINVAL; | ||
537 | } | ||
538 | |||
539 | if (tb[NDA_DST] == NULL) | ||
540 | return -EINVAL; | ||
541 | 525 | ||
542 | if (nla_len(tb[NDA_DST]) != sizeof(__be32)) | 526 | if (tb[NDA_DST]) { |
543 | return -EAFNOSUPPORT; | 527 | if (nla_len(tb[NDA_DST]) != sizeof(__be32)) |
528 | return -EAFNOSUPPORT; | ||
544 | 529 | ||
545 | ip = nla_get_be32(tb[NDA_DST]); | 530 | *ip = nla_get_be32(tb[NDA_DST]); |
531 | } else { | ||
532 | *ip = htonl(INADDR_ANY); | ||
533 | } | ||
546 | 534 | ||
547 | if (tb[NDA_PORT]) { | 535 | if (tb[NDA_PORT]) { |
548 | if (nla_len(tb[NDA_PORT]) != sizeof(__be16)) | 536 | if (nla_len(tb[NDA_PORT]) != sizeof(__be16)) |
549 | return -EINVAL; | 537 | return -EINVAL; |
550 | port = nla_get_be16(tb[NDA_PORT]); | 538 | *port = nla_get_be16(tb[NDA_PORT]); |
551 | } else | 539 | } else { |
552 | port = vxlan->dst_port; | 540 | *port = vxlan->dst_port; |
541 | } | ||
553 | 542 | ||
554 | if (tb[NDA_VNI]) { | 543 | if (tb[NDA_VNI]) { |
555 | if (nla_len(tb[NDA_VNI]) != sizeof(u32)) | 544 | if (nla_len(tb[NDA_VNI]) != sizeof(u32)) |
556 | return -EINVAL; | 545 | return -EINVAL; |
557 | vni = nla_get_u32(tb[NDA_VNI]); | 546 | *vni = nla_get_u32(tb[NDA_VNI]); |
558 | } else | 547 | } else { |
559 | vni = vxlan->default_dst.remote_vni; | 548 | *vni = vxlan->default_dst.remote_vni; |
549 | } | ||
560 | 550 | ||
561 | if (tb[NDA_IFINDEX]) { | 551 | if (tb[NDA_IFINDEX]) { |
562 | struct net_device *tdev; | 552 | struct net_device *tdev; |
563 | 553 | ||
564 | if (nla_len(tb[NDA_IFINDEX]) != sizeof(u32)) | 554 | if (nla_len(tb[NDA_IFINDEX]) != sizeof(u32)) |
565 | return -EINVAL; | 555 | return -EINVAL; |
566 | ifindex = nla_get_u32(tb[NDA_IFINDEX]); | 556 | *ifindex = nla_get_u32(tb[NDA_IFINDEX]); |
567 | tdev = dev_get_by_index(net, ifindex); | 557 | tdev = dev_get_by_index(net, *ifindex); |
568 | if (!tdev) | 558 | if (!tdev) |
569 | return -EADDRNOTAVAIL; | 559 | return -EADDRNOTAVAIL; |
570 | dev_put(tdev); | 560 | dev_put(tdev); |
571 | } else | 561 | } else { |
572 | ifindex = 0; | 562 | *ifindex = 0; |
563 | } | ||
564 | |||
565 | return 0; | ||
566 | } | ||
567 | |||
568 | /* Add static entry (via netlink) */ | ||
569 | static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], | ||
570 | struct net_device *dev, | ||
571 | const unsigned char *addr, u16 flags) | ||
572 | { | ||
573 | struct vxlan_dev *vxlan = netdev_priv(dev); | ||
574 | /* struct net *net = dev_net(vxlan->dev); */ | ||
575 | __be32 ip; | ||
576 | __be16 port; | ||
577 | u32 vni, ifindex; | ||
578 | int err; | ||
579 | |||
580 | if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_REACHABLE))) { | ||
581 | pr_info("RTM_NEWNEIGH with invalid state %#x\n", | ||
582 | ndm->ndm_state); | ||
583 | return -EINVAL; | ||
584 | } | ||
585 | |||
586 | if (tb[NDA_DST] == NULL) | ||
587 | return -EINVAL; | ||
588 | |||
589 | err = vxlan_fdb_parse(tb, vxlan, &ip, &port, &vni, &ifindex); | ||
590 | if (err) | ||
591 | return err; | ||
573 | 592 | ||
574 | spin_lock_bh(&vxlan->hash_lock); | 593 | spin_lock_bh(&vxlan->hash_lock); |
575 | err = vxlan_fdb_create(vxlan, addr, ip, ndm->ndm_state, flags, | 594 | err = vxlan_fdb_create(vxlan, addr, ip, ndm->ndm_state, flags, |