diff options
author | Yi Zou <yi.zou@intel.com> | 2009-08-31 08:33:40 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-09-01 04:24:36 -0400 |
commit | 579496865cf4ea429146382d62047ffdbaab0dee (patch) | |
tree | 2795de93733e743d23e716f40506bdd2373766af /net/dcb | |
parent | 6fa382af61338908e5713234bcee598423f661c3 (diff) |
dcbnl: Add implementations of dcbnl setapp/getapp commands
Implements the dcbnl netlink setapp/getapp pair. When a setapp/getapp
is received, dcbnl would just pass on to dcbnl_rtnl_op.setapp/getapp
that are supposed to be implemented by the low level drivers.
Signed-off-by: Yi Zou <yi.zou@intel.com>
Acked-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dcb')
-rw-r--r-- | net/dcb/dcbnl.c | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 4046468b219e..e0879bfb7dd5 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c | |||
@@ -544,6 +544,120 @@ static int dcbnl_setpfcstate(struct net_device *netdev, struct nlattr **tb, | |||
544 | return ret; | 544 | return ret; |
545 | } | 545 | } |
546 | 546 | ||
547 | static int dcbnl_getapp(struct net_device *netdev, struct nlattr **tb, | ||
548 | u32 pid, u32 seq, u16 flags) | ||
549 | { | ||
550 | struct sk_buff *dcbnl_skb; | ||
551 | struct nlmsghdr *nlh; | ||
552 | struct dcbmsg *dcb; | ||
553 | struct nlattr *app_nest; | ||
554 | struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; | ||
555 | u16 id; | ||
556 | u8 up, idtype; | ||
557 | int ret = -EINVAL; | ||
558 | |||
559 | if (!tb[DCB_ATTR_APP] || !netdev->dcbnl_ops->getapp) | ||
560 | goto out; | ||
561 | |||
562 | ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], | ||
563 | dcbnl_app_nest); | ||
564 | if (ret) | ||
565 | goto out; | ||
566 | |||
567 | ret = -EINVAL; | ||
568 | /* all must be non-null */ | ||
569 | if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || | ||
570 | (!app_tb[DCB_APP_ATTR_ID])) | ||
571 | goto out; | ||
572 | |||
573 | /* either by eth type or by socket number */ | ||
574 | idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); | ||
575 | if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && | ||
576 | (idtype != DCB_APP_IDTYPE_PORTNUM)) | ||
577 | goto out; | ||
578 | |||
579 | id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); | ||
580 | up = netdev->dcbnl_ops->getapp(netdev, idtype, id); | ||
581 | |||
582 | /* send this back */ | ||
583 | dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
584 | if (!dcbnl_skb) | ||
585 | goto out; | ||
586 | |||
587 | nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); | ||
588 | dcb = NLMSG_DATA(nlh); | ||
589 | dcb->dcb_family = AF_UNSPEC; | ||
590 | dcb->cmd = DCB_CMD_GAPP; | ||
591 | |||
592 | app_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_APP); | ||
593 | ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_IDTYPE, idtype); | ||
594 | if (ret) | ||
595 | goto out_cancel; | ||
596 | |||
597 | ret = nla_put_u16(dcbnl_skb, DCB_APP_ATTR_ID, id); | ||
598 | if (ret) | ||
599 | goto out_cancel; | ||
600 | |||
601 | ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_PRIORITY, up); | ||
602 | if (ret) | ||
603 | goto out_cancel; | ||
604 | |||
605 | nla_nest_end(dcbnl_skb, app_nest); | ||
606 | nlmsg_end(dcbnl_skb, nlh); | ||
607 | |||
608 | ret = rtnl_unicast(dcbnl_skb, &init_net, pid); | ||
609 | if (ret) | ||
610 | goto nlmsg_failure; | ||
611 | |||
612 | goto out; | ||
613 | |||
614 | out_cancel: | ||
615 | nla_nest_cancel(dcbnl_skb, app_nest); | ||
616 | nlmsg_failure: | ||
617 | kfree_skb(dcbnl_skb); | ||
618 | out: | ||
619 | return ret; | ||
620 | } | ||
621 | |||
622 | static int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb, | ||
623 | u32 pid, u32 seq, u16 flags) | ||
624 | { | ||
625 | int ret = -EINVAL; | ||
626 | u16 id; | ||
627 | u8 up, idtype; | ||
628 | struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; | ||
629 | |||
630 | if (!tb[DCB_ATTR_APP] || !netdev->dcbnl_ops->setapp) | ||
631 | goto out; | ||
632 | |||
633 | ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], | ||
634 | dcbnl_app_nest); | ||
635 | if (ret) | ||
636 | goto out; | ||
637 | |||
638 | ret = -EINVAL; | ||
639 | /* all must be non-null */ | ||
640 | if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || | ||
641 | (!app_tb[DCB_APP_ATTR_ID]) || | ||
642 | (!app_tb[DCB_APP_ATTR_PRIORITY])) | ||
643 | goto out; | ||
644 | |||
645 | /* either by eth type or by socket number */ | ||
646 | idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); | ||
647 | if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && | ||
648 | (idtype != DCB_APP_IDTYPE_PORTNUM)) | ||
649 | goto out; | ||
650 | |||
651 | id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); | ||
652 | up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]); | ||
653 | |||
654 | ret = dcbnl_reply(netdev->dcbnl_ops->setapp(netdev, idtype, id, up), | ||
655 | RTM_SETDCB, DCB_CMD_SAPP, DCB_ATTR_APP, | ||
656 | pid, seq, flags); | ||
657 | out: | ||
658 | return ret; | ||
659 | } | ||
660 | |||
547 | static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb, | 661 | static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb, |
548 | u32 pid, u32 seq, u16 flags, int dir) | 662 | u32 pid, u32 seq, u16 flags, int dir) |
549 | { | 663 | { |
@@ -1101,6 +1215,14 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
1101 | ret = dcbnl_bcn_setcfg(netdev, tb, pid, nlh->nlmsg_seq, | 1215 | ret = dcbnl_bcn_setcfg(netdev, tb, pid, nlh->nlmsg_seq, |
1102 | nlh->nlmsg_flags); | 1216 | nlh->nlmsg_flags); |
1103 | goto out; | 1217 | goto out; |
1218 | case DCB_CMD_GAPP: | ||
1219 | ret = dcbnl_getapp(netdev, tb, pid, nlh->nlmsg_seq, | ||
1220 | nlh->nlmsg_flags); | ||
1221 | goto out; | ||
1222 | case DCB_CMD_SAPP: | ||
1223 | ret = dcbnl_setapp(netdev, tb, pid, nlh->nlmsg_seq, | ||
1224 | nlh->nlmsg_flags); | ||
1225 | goto out; | ||
1104 | default: | 1226 | default: |
1105 | goto errout; | 1227 | goto errout; |
1106 | } | 1228 | } |