* iproute2 patch introducing mtu/txqlen/weight via rtnetlink
@ 2004-09-09 16:48 Thomas Graf
2004-09-09 17:33 ` David S. Miller
0 siblings, 1 reply; 9+ messages in thread
From: Thomas Graf @ 2004-09-09 16:48 UTC (permalink / raw)
To: Jamal Hadi Salim, Stephen Hemminger, Eric Lemoine; +Cc: netdev
- Convert mtu and txqlen to use rtnetlink instead of ioctl.
- Introduces weight.
- Updates local copy of rtnetlink.h.
Against iproute2-2.6.9-jamal, tested and working.
Will look into remaining ioctls later.
diff -urN iproute2-2.6.9-jamal.orig/include/linux/rtnetlink.h iproute2-2.6.9-jamal/include/linux/rtnetlink.h
--- iproute2-2.6.9-jamal.orig/include/linux/rtnetlink.h 2004-09-08 19:23:18.000000000 +0200
+++ iproute2-2.6.9-jamal/include/linux/rtnetlink.h 2004-09-08 19:41:36.000000000 +0200
@@ -561,6 +561,12 @@
#define IFLA_WIRELESS IFLA_WIRELESS
IFLA_PROTINFO, /* Protocol specific information for a link */
#define IFLA_PROTINFO IFLA_PROTINFO
+ IFLA_TXQLEN,
+#define IFLA_TXQLEN IFLA_TXQLEN
+ IFLA_MAP,
+#define IFLA_MAP IFLA_MAP
+ IFLA_WEIGHT,
+#define IFLA_WEIGHT IFLA_WEIGHT
__IFLA_MAX
};
@@ -693,6 +699,88 @@
/* End of information exported to user level */
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+
+static __inline__ int rtattr_strcmp(const struct rtattr *rta, const char *str)
+{
+ int len = strlen(str) + 1;
+ return len > rta->rta_len || memcmp(RTA_DATA(rta), str, len);
+}
+
+extern int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len);
+
+extern struct sock *rtnl;
+
+struct rtnetlink_link
+{
+ int (*doit)(struct sk_buff *, struct nlmsghdr*, void *attr);
+ int (*dumpit)(struct sk_buff *, struct netlink_callback *cb);
+};
+
+extern struct rtnetlink_link * rtnetlink_links[NPROTO];
+extern int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb);
+extern int rtnetlink_send(struct sk_buff *skb, u32 pid, u32 group, int echo);
+extern int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics);
+
+extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data);
+
+#define RTA_PUT(skb, attrtype, attrlen, data) \
+({ if (unlikely(skb_tailroom(skb) < (int)RTA_SPACE(attrlen))) \
+ goto rtattr_failure; \
+ __rta_fill(skb, attrtype, attrlen, data); })
+
+static inline struct rtattr *
+__rta_reserve(struct sk_buff *skb, int attrtype, int attrlen)
+{
+ struct rtattr *rta;
+ int size = RTA_LENGTH(attrlen);
+
+ rta = (struct rtattr*)skb_put(skb, RTA_ALIGN(size));
+ rta->rta_type = attrtype;
+ rta->rta_len = size;
+ return rta;
+}
+
+#define __RTA_PUT(skb, attrtype, attrlen) \
+({ if (unlikely(skb_tailroom(skb) < (int)RTA_SPACE(attrlen))) \
+ goto rtattr_failure; \
+ __rta_reserve(skb, attrtype, attrlen); })
+
+extern void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change);
+
+extern struct semaphore rtnl_sem;
+
+#define rtnl_shlock() down(&rtnl_sem)
+#define rtnl_shlock_nowait() down_trylock(&rtnl_sem)
+
+#define rtnl_shunlock() do { up(&rtnl_sem); \
+ if (rtnl && rtnl->sk_receive_queue.qlen) \
+ rtnl->sk_data_ready(rtnl, 0); \
+ } while(0)
+
+extern void rtnl_lock(void);
+extern void rtnl_unlock(void);
+extern void rtnetlink_init(void);
+
+#define ASSERT_RTNL() do { \
+ if (unlikely(down_trylock(&rtnl_sem) == 0)) { \
+ up(&rtnl_sem); \
+ printk(KERN_ERR "RTNL: assertion failed at %s (%d)\n", \
+ __FILE__, __LINE__); \
+ dump_stack(); \
+ } \
+} while(0)
+
+#define BUG_TRAP(x) do { \
+ if (unlikely(!(x))) { \
+ printk(KERN_ERR "KERNEL: assertion (%s) failed at %s (%d)\n", \
+ #x, __FILE__ , __LINE__); \
+ } \
+} while(0)
+
+#endif /* __KERNEL__ */
#endif /* __LINUX_RTNETLINK_H */
diff -urN iproute2-2.6.9-jamal.orig/ip/ipaddress.c iproute2-2.6.9-jamal/ip/ipaddress.c
--- iproute2-2.6.9-jamal.orig/ip/ipaddress.c 2004-09-08 19:23:18.000000000 +0200
+++ iproute2-2.6.9-jamal/ip/ipaddress.c 2004-09-08 19:57:30.000000000 +0200
@@ -182,6 +182,8 @@
fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
if (tb[IFLA_QDISC])
fprintf(fp, "qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC]));
+ if (tb[IFLA_WEIGHT])
+ fprintf(fp, "weight %u ", *(uint32_t*)RTA_DATA(tb[IFLA_WEIGHT]));
#ifdef IFLA_MASTER
if (tb[IFLA_MASTER]) {
SPRINT_BUF(b1);
diff -urN iproute2-2.6.9-jamal.orig/ip/iplink.c iproute2-2.6.9-jamal/ip/iplink.c
--- iproute2-2.6.9-jamal.orig/ip/iplink.c 2004-09-08 19:23:18.000000000 +0200
+++ iproute2-2.6.9-jamal/ip/iplink.c 2004-09-08 19:51:33.000000000 +0200
@@ -21,6 +21,7 @@
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <linux/sockios.h>
+#include <linux/rtnetlink.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
@@ -46,7 +47,8 @@
fprintf(stderr, " txqueuelen PACKETS |\n");
fprintf(stderr, " name NEWNAME |\n");
fprintf(stderr, " address LLADDR | broadcast LLADDR |\n");
- fprintf(stderr, " mtu MTU }\n");
+ fprintf(stderr, " mtu MTU |\n");
+ fprintf(stderr, " weight WEIGHT }\n");
fprintf(stderr, " ip link show [ DEVICE ]\n");
exit(-1);
}
@@ -130,50 +132,6 @@
return err;
}
-static int set_qlen(char *dev, int qlen)
-{
- struct ifreq ifr;
- int s;
-
- s = get_ctl_fd();
- if (s < 0)
- return -1;
-
- memset(&ifr, 0, sizeof(ifr));
- strcpy(ifr.ifr_name, dev);
- ifr.ifr_qlen = qlen;
- if (ioctl(s, SIOCSIFTXQLEN, &ifr) < 0) {
- perror("SIOCSIFXQLEN");
- close(s);
- return -1;
- }
- close(s);
-
- return 0;
-}
-
-static int set_mtu(char *dev, int mtu)
-{
- struct ifreq ifr;
- int s;
-
- s = get_ctl_fd();
- if (s < 0)
- return -1;
-
- memset(&ifr, 0, sizeof(ifr));
- strcpy(ifr.ifr_name, dev);
- ifr.ifr_mtu = mtu;
- if (ioctl(s, SIOCSIFMTU, &ifr) < 0) {
- perror("SIOCSIFMTU");
- close(s);
- return -1;
- }
- close(s);
-
- return 0;
-}
-
static int get_address(char *dev, int *htype)
{
struct ifreq ifr;
@@ -249,19 +207,36 @@
return 0;
}
+struct link_request
+{
+ struct nlmsghdr nl_msg;
+ struct ifinfomsg ifi;
+ char buf[256];
+};
+
static int do_set(int argc, char **argv)
{
char *dev = NULL;
__u32 mask = 0;
__u32 flags = 0;
- int qlen = -1;
- int mtu = -1;
+ int32_t qlen = -1;
+ int32_t mtu = -1;
+ int32_t weight = -1;
char *newaddr = NULL;
char *newbrd = NULL;
struct ifreq ifr0, ifr1;
char *newname = NULL;
int htype, halen;
+ struct rtnl_handle rth;
+
+ struct link_request req = {
+ .nl_msg = {
+ .nlmsg_type = RTM_SETLINK,
+ .nlmsg_flags = NLM_F_REQUEST,
+ .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
+ },
+ };
while (argc > 0) {
if (strcmp(*argv, "up") == 0) {
@@ -288,12 +263,14 @@
duparg("txqueuelen", *argv);
if (get_integer(&qlen, *argv, 0))
invarg("Invalid \"txqueuelen\" value\n", *argv);
+ addattr_l(&req.nl_msg, sizeof(req), IFLA_TXQLEN, &qlen, sizeof(qlen));
} else if (strcmp(*argv, "mtu") == 0) {
NEXT_ARG();
if (mtu != -1)
duparg("mtu", *argv);
if (get_integer(&mtu, *argv, 0))
invarg("Invalid \"mtu\" value\n", *argv);
+ addattr_l(&req.nl_msg, sizeof(req), IFLA_MTU, &mtu, sizeof(mtu));
} else if (strcmp(*argv, "multicast") == 0) {
NEXT_ARG();
mask |= IFF_MULTICAST;
@@ -339,6 +316,13 @@
flags |= IFF_NOARP;
} else
return on_off("noarp");
+ } else if (matches(*argv, "weight") == 0) {
+ NEXT_ARG();
+ if (weight != -1)
+ duparg("weight", *argv);
+ if (get_integer(&weight, *argv, 0))
+ invarg("Invalid \"weight\" value\n", *argv);
+ addattr_l(&req.nl_msg, sizeof(req), IFLA_WEIGHT, &weight, sizeof(weight));
#ifdef IFF_DYNAMIC
} else if (matches(*argv, "dynamic") == 0) {
NEXT_ARG();
@@ -387,14 +371,6 @@
return -1;
dev = newname;
}
- if (qlen != -1) {
- if (set_qlen(dev, qlen) < 0)
- return -1;
- }
- if (mtu != -1) {
- if (set_mtu(dev, mtu) < 0)
- return -1;
- }
if (newaddr || newbrd) {
if (newbrd) {
if (set_address(&ifr1, 1) < 0)
@@ -407,6 +383,20 @@
}
if (mask)
return do_chflags(dev, flags, mask);
+
+ if (rtnl_open(&rth, 0) < 0)
+ exit(1);
+
+ ll_init_map(&rth);
+
+ if ((req.ifi.ifi_index = ll_name_to_index(dev)) == 0) {
+ fprintf(stderr, "Cannot find device \"%s\"\n", dev);
+ return -1;
+ }
+
+ if (rtnl_talk(&rth, &req.nl_msg, 0, 0, NULL, NULL, NULL) < 0)
+ exit(2);
+
return 0;
}
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: iproute2 patch introducing mtu/txqlen/weight via rtnetlink 2004-09-09 16:48 iproute2 patch introducing mtu/txqlen/weight via rtnetlink Thomas Graf @ 2004-09-09 17:33 ` David S. Miller 2004-09-09 17:54 ` Thomas Graf 0 siblings, 1 reply; 9+ messages in thread From: David S. Miller @ 2004-09-09 17:33 UTC (permalink / raw) To: Thomas Graf; +Cc: hadi, shemminger, eric.lemoine, netdev On Thu, 9 Sep 2004 18:48:34 +0200 Thomas Graf <tgraf@suug.ch> wrote: > - Convert mtu and txqlen to use rtnetlink instead of ioctl. > - Introduces weight. > - Updates local copy of rtnetlink.h. > > Against iproute2-2.6.9-jamal, tested and working. > Will look into remaining ioctls later. Please don't blindly update rtnetlink.h in iproute2 with the current kernel copy. The "__KERNEL__" ifdef area is omitted on purpose, yet you added it back in. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: iproute2 patch introducing mtu/txqlen/weight via rtnetlink 2004-09-09 17:33 ` David S. Miller @ 2004-09-09 17:54 ` Thomas Graf 2004-09-10 1:33 ` YOSHIFUJI Hideaki / 吉藤英明 0 siblings, 1 reply; 9+ messages in thread From: Thomas Graf @ 2004-09-09 17:54 UTC (permalink / raw) To: David S. Miller; +Cc: hadi, shemminger, eric.lemoine, netdev * David S. Miller <20040909103344.5a448b01.davem@davemloft.net> 2004-09-09 10:33 > On Thu, 9 Sep 2004 18:48:34 +0200 > Thomas Graf <tgraf@suug.ch> wrote: > > > - Convert mtu and txqlen to use rtnetlink instead of ioctl. > > - Introduces weight. > > - Updates local copy of rtnetlink.h. > > > > Against iproute2-2.6.9-jamal, tested and working. > > Will look into remaining ioctls later. > > Please don't blindly update rtnetlink.h in iproute2 with > the current kernel copy. The "__KERNEL__" ifdef area > is omitted on purpose, yet you added it back in. Sorry, included old patch, this is a correct one: diff -Nru iproute2-2.6.9-jamal.orig/include/linux/rtnetlink.h iproute2-2.6.9-jamal/include/linux/rtnetlink.h --- iproute2-2.6.9-jamal.orig/include/linux/rtnetlink.h 2004-09-08 19:23:18.000000000 +0200 +++ iproute2-2.6.9-jamal/include/linux/rtnetlink.h 2004-09-09 19:46:26.000000000 +0200 @@ -561,6 +561,12 @@ #define IFLA_WIRELESS IFLA_WIRELESS IFLA_PROTINFO, /* Protocol specific information for a link */ #define IFLA_PROTINFO IFLA_PROTINFO + IFLA_TXQLEN, +#define IFLA_TXQLEN IFLA_TXQLEN + IFLA_MAP, +#define IFLA_MAP IFLA_MAP + IFLA_WEIGHT, +#define IFLA_WEIGHT IFLA_WEIGHT __IFLA_MAX }; diff -Nru iproute2-2.6.9-jamal.orig/ip/ipaddress.c iproute2-2.6.9-jamal/ip/ipaddress.c --- iproute2-2.6.9-jamal.orig/ip/ipaddress.c 2004-09-08 19:23:18.000000000 +0200 +++ iproute2-2.6.9-jamal/ip/ipaddress.c 2004-09-08 19:57:30.000000000 +0200 @@ -182,6 +182,8 @@ fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU])); if (tb[IFLA_QDISC]) fprintf(fp, "qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC])); + if (tb[IFLA_WEIGHT]) + fprintf(fp, "weight %u ", *(uint32_t*)RTA_DATA(tb[IFLA_WEIGHT])); #ifdef IFLA_MASTER if (tb[IFLA_MASTER]) { SPRINT_BUF(b1); diff -Nru iproute2-2.6.9-jamal.orig/ip/iplink.c iproute2-2.6.9-jamal/ip/iplink.c --- iproute2-2.6.9-jamal.orig/ip/iplink.c 2004-09-08 19:23:18.000000000 +0200 +++ iproute2-2.6.9-jamal/ip/iplink.c 2004-09-09 19:50:51.000000000 +0200 @@ -21,6 +21,7 @@ #include <linux/if_packet.h> #include <linux/if_ether.h> #include <linux/sockios.h> +#include <linux/rtnetlink.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> @@ -46,7 +47,8 @@ fprintf(stderr, " txqueuelen PACKETS |\n"); fprintf(stderr, " name NEWNAME |\n"); fprintf(stderr, " address LLADDR | broadcast LLADDR |\n"); - fprintf(stderr, " mtu MTU }\n"); + fprintf(stderr, " mtu MTU |\n"); + fprintf(stderr, " weight WEIGHT }\n"); fprintf(stderr, " ip link show [ DEVICE ]\n"); exit(-1); } @@ -130,50 +132,6 @@ return err; } -static int set_qlen(char *dev, int qlen) -{ - struct ifreq ifr; - int s; - - s = get_ctl_fd(); - if (s < 0) - return -1; - - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, dev); - ifr.ifr_qlen = qlen; - if (ioctl(s, SIOCSIFTXQLEN, &ifr) < 0) { - perror("SIOCSIFXQLEN"); - close(s); - return -1; - } - close(s); - - return 0; -} - -static int set_mtu(char *dev, int mtu) -{ - struct ifreq ifr; - int s; - - s = get_ctl_fd(); - if (s < 0) - return -1; - - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, dev); - ifr.ifr_mtu = mtu; - if (ioctl(s, SIOCSIFMTU, &ifr) < 0) { - perror("SIOCSIFMTU"); - close(s); - return -1; - } - close(s); - - return 0; -} - static int get_address(char *dev, int *htype) { struct ifreq ifr; @@ -249,19 +207,39 @@ return 0; } +struct link_request +{ + struct nlmsghdr nl_msg; + struct ifinfomsg ifi; + char buf[256]; +}; + static int do_set(int argc, char **argv) { char *dev = NULL; __u32 mask = 0; __u32 flags = 0; - int qlen = -1; - int mtu = -1; + int32_t qlen = -1; + int32_t mtu = -1; + int32_t weight = -1; char *newaddr = NULL; char *newbrd = NULL; struct ifreq ifr0, ifr1; char *newname = NULL; int htype, halen; + struct rtnl_handle rth; + + struct link_request req = { + .nl_msg = { + .nlmsg_type = RTM_SETLINK, + .nlmsg_flags = NLM_F_REQUEST, + .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), + }, + .ifi = { + .ifi_family = PF_PACKET, + }, + }; while (argc > 0) { if (strcmp(*argv, "up") == 0) { @@ -288,12 +266,14 @@ duparg("txqueuelen", *argv); if (get_integer(&qlen, *argv, 0)) invarg("Invalid \"txqueuelen\" value\n", *argv); + addattr_l(&req.nl_msg, sizeof(req), IFLA_TXQLEN, &qlen, sizeof(qlen)); } else if (strcmp(*argv, "mtu") == 0) { NEXT_ARG(); if (mtu != -1) duparg("mtu", *argv); if (get_integer(&mtu, *argv, 0)) invarg("Invalid \"mtu\" value\n", *argv); + addattr_l(&req.nl_msg, sizeof(req), IFLA_MTU, &mtu, sizeof(mtu)); } else if (strcmp(*argv, "multicast") == 0) { NEXT_ARG(); mask |= IFF_MULTICAST; @@ -339,6 +319,13 @@ flags |= IFF_NOARP; } else return on_off("noarp"); + } else if (matches(*argv, "weight") == 0) { + NEXT_ARG(); + if (weight != -1) + duparg("weight", *argv); + if (get_integer(&weight, *argv, 0)) + invarg("Invalid \"weight\" value\n", *argv); + addattr_l(&req.nl_msg, sizeof(req), IFLA_WEIGHT, &weight, sizeof(weight)); #ifdef IFF_DYNAMIC } else if (matches(*argv, "dynamic") == 0) { NEXT_ARG(); @@ -387,14 +374,6 @@ return -1; dev = newname; } - if (qlen != -1) { - if (set_qlen(dev, qlen) < 0) - return -1; - } - if (mtu != -1) { - if (set_mtu(dev, mtu) < 0) - return -1; - } if (newaddr || newbrd) { if (newbrd) { if (set_address(&ifr1, 1) < 0) @@ -407,6 +386,20 @@ } if (mask) return do_chflags(dev, flags, mask); + + if (rtnl_open(&rth, 0) < 0) + exit(1); + + ll_init_map(&rth); + + if ((req.ifi.ifi_index = ll_name_to_index(dev)) == 0) { + fprintf(stderr, "Cannot find device \"%s\"\n", dev); + return -1; + } + + if (rtnl_talk(&rth, &req.nl_msg, 0, 0, NULL, NULL, NULL) < 0) + exit(2); + return 0; } ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: iproute2 patch introducing mtu/txqlen/weight via rtnetlink 2004-09-09 17:54 ` Thomas Graf @ 2004-09-10 1:33 ` YOSHIFUJI Hideaki / 吉藤英明 2004-09-10 9:29 ` Thomas Graf 0 siblings, 1 reply; 9+ messages in thread From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-09-10 1:33 UTC (permalink / raw) To: tgraf; +Cc: davem, hadi, shemminger, eric.lemoine, netdev, yoshfuji In article <20040909175411.GB19155@postel.suug.ch> (at Thu, 9 Sep 2004 19:54:11 +0200), Thomas Graf <tgraf@suug.ch> says: > * David S. Miller <20040909103344.5a448b01.davem@davemloft.net> 2004-09-09 10:33 > > On Thu, 9 Sep 2004 18:48:34 +0200 > > Thomas Graf <tgraf@suug.ch> wrote: > > > > > - Convert mtu and txqlen to use rtnetlink instead of ioctl. > > > - Introduces weight. > > > - Updates local copy of rtnetlink.h. > > > > > > Against iproute2-2.6.9-jamal, tested and working. > > > Will look into remaining ioctls later. > > > > Please don't blindly update rtnetlink.h in iproute2 with > > the current kernel copy. The "__KERNEL__" ifdef area > > is omitted on purpose, yet you added it back in. > > Sorry, included old patch, this is a correct one: Well, I think we should maintain old ioctl path for backward compatibility. (or ifdefs at least.) -- Hideaki YOSHIFUJI @ USAGI Project <yoshfuji@linux-ipv6.org> GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: iproute2 patch introducing mtu/txqlen/weight via rtnetlink 2004-09-10 1:33 ` YOSHIFUJI Hideaki / 吉藤英明 @ 2004-09-10 9:29 ` Thomas Graf 2004-09-10 9:40 ` Stephen Hemminger 0 siblings, 1 reply; 9+ messages in thread From: Thomas Graf @ 2004-09-10 9:29 UTC (permalink / raw) To: YOSHIFUJI Hideaki / ?$B5HF#1QL@ Cc: davem, hadi, shemminger, eric.lemoine, netdev * YOSHIFUJI Hideaki / ?$B5HF#1QL@ <20040910.103341.28767986.yoshfuji@wide.ad.jp> 2004-09-10 10:33 > > > On Thu, 9 Sep 2004 18:48:34 +0200 > > > Thomas Graf <tgraf@suug.ch> wrote: > > > > > > > - Convert mtu and txqlen to use rtnetlink instead of ioctl. > > > > - Introduces weight. > > > > - Updates local copy of rtnetlink.h. > Well, I think we should maintain old ioctl path for backward compatibility. > (or ifdefs at least.) I agree, however I think that the only good solution would be to have iproute2 negotiate with the kernel at runtime. I therefore suggest to consider my iproute2 patches as development only and don't include them in any releases as long as the whole 'new iproute2 with old kernel' issue, also affecting the new tc-actions, has been resolved. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: iproute2 patch introducing mtu/txqlen/weight via rtnetlink 2004-09-10 9:29 ` Thomas Graf @ 2004-09-10 9:40 ` Stephen Hemminger 2004-09-10 13:16 ` jamal 0 siblings, 1 reply; 9+ messages in thread From: Stephen Hemminger @ 2004-09-10 9:40 UTC (permalink / raw) To: Thomas Graf Cc: YOSHIFUJI Hideaki / ?$B5HF#1QL@, davem, hadi, eric.lemoine, netdev Unless there is some compelling reason, I think that keeping the old ioctl interface for a least a year until the kernel changes become more ubiquitous. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: iproute2 patch introducing mtu/txqlen/weight via rtnetlink 2004-09-10 9:40 ` Stephen Hemminger @ 2004-09-10 13:16 ` jamal 2004-09-10 16:55 ` Thomas Graf 2004-09-10 21:14 ` David S. Miller 0 siblings, 2 replies; 9+ messages in thread From: jamal @ 2004-09-10 13:16 UTC (permalink / raw) To: Stephen Hemminger Cc: Thomas Graf, YOSHIFUJI Hideaki / ?$B5HF#1QL@, davem, eric.lemoine, netdev On Fri, 2004-09-10 at 05:40, Stephen Hemminger wrote: > Unless there is some compelling reason, I think that keeping the old ioctl > interface for a least a year until the kernel changes become more ubiquitous. I think that iproute2 should first attempt to use netlink and on failure switch to ioctls. Maybe Thomas can create such a patch. cheers, jamal ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: iproute2 patch introducing mtu/txqlen/weight via rtnetlink 2004-09-10 13:16 ` jamal @ 2004-09-10 16:55 ` Thomas Graf 2004-09-10 21:14 ` David S. Miller 1 sibling, 0 replies; 9+ messages in thread From: Thomas Graf @ 2004-09-10 16:55 UTC (permalink / raw) To: jamal Cc: Stephen Hemminger, YOSHIFUJI Hideaki / ?$B5HF#1QL@, davem, eric.lemoine, netdev * jamal <1094822205.1125.113.camel@jzny.localdomain> 2004-09-10 09:16 > > On Fri, 2004-09-10 at 05:40, Stephen Hemminger wrote: > > Unless there is some compelling reason, I think that keeping the old ioctl > > interface for a least a year until the kernel changes become more ubiquitous. > > I think that iproute2 should first attempt to use netlink and on failure > switch to ioctls. > Maybe Thomas can create such a patch. - Uses rtnetlink whenver possible and falls back to ioctl if the rtnetlink call fails or one of the changes was not successful. Not 100% perfect yet but you'll get the point. - Fixes memory corruption issue. buffer for address and brd was too small (14) for bigger addresses, e.g. interfaces with ipv6 ll addresses. Introduced a ADDRBUFSIZ and a check in ll_init_map to avoid further problems. - Uses ifinfomsg.ifi_type instead of getting hw type from packet socket. I hope this is correct. just a small hack... diff -Nru iproute2-2.6.9-jamal.orig/include/linux/rtnetlink.h iproute2-2.6.9-jamal/include/linux/rtnetlink.h --- iproute2-2.6.9-jamal.orig/include/linux/rtnetlink.h 2004-09-08 19:23:18.000000000 +0200 +++ iproute2-2.6.9-jamal/include/linux/rtnetlink.h 2004-09-10 17:51:28.000000000 +0200 @@ -561,6 +561,12 @@ #define IFLA_WIRELESS IFLA_WIRELESS IFLA_PROTINFO, /* Protocol specific information for a link */ #define IFLA_PROTINFO IFLA_PROTINFO + IFLA_TXQLEN, +#define IFLA_TXQLEN IFLA_TXQLEN + IFLA_MAP, +#define IFLA_MAP IFLA_MAP + IFLA_WEIGHT, +#define IFLA_WEIGHT IFLA_WEIGHT __IFLA_MAX }; diff -Nru iproute2-2.6.9-jamal.orig/include/ll_map.h iproute2-2.6.9-jamal/include/ll_map.h --- iproute2-2.6.9-jamal.orig/include/ll_map.h 2004-09-08 19:23:18.000000000 +0200 +++ iproute2-2.6.9-jamal/include/ll_map.h 2004-09-10 18:37:45.000000000 +0200 @@ -1,12 +1,17 @@ #ifndef __LL_MAP_H__ #define __LL_MAP_H__ 1 +#define ADDRBUFSIZ 32 + extern int ll_remember_index(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg); extern int ll_init_map(struct rtnl_handle *rth); extern int ll_name_to_index(char *name); extern const char *ll_index_to_name(int idx); extern const char *ll_idx_n2a(int idx, char *buf); extern int ll_index_to_type(int idx); +extern int ll_index_to_alen(int idx); +extern unsigned char *ll_index_to_addr(int idx); +extern unsigned char *ll_index_to_brd(int idx); extern unsigned ll_index_to_flags(int idx); #endif /* __LL_MAP_H__ */ diff -Nru iproute2-2.6.9-jamal.orig/ip/ipaddress.c iproute2-2.6.9-jamal/ip/ipaddress.c --- iproute2-2.6.9-jamal.orig/ip/ipaddress.c 2004-09-08 19:23:18.000000000 +0200 +++ iproute2-2.6.9-jamal/ip/ipaddress.c 2004-09-10 17:52:38.000000000 +0200 @@ -182,6 +182,10 @@ fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU])); if (tb[IFLA_QDISC]) fprintf(fp, "qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC])); +#ifdef IFLA_WEIGT + if (tb[IFLA_WEIGHT]) + fprintf(fp, "weight %u ", *(uint32_t*)RTA_DATA(tb[IFLA_WEIGHT])); +#endif #ifdef IFLA_MASTER if (tb[IFLA_MASTER]) { SPRINT_BUF(b1); diff -Nru iproute2-2.6.9-jamal.orig/ip/iplink.c iproute2-2.6.9-jamal/ip/iplink.c --- iproute2-2.6.9-jamal.orig/ip/iplink.c 2004-09-08 19:23:18.000000000 +0200 +++ iproute2-2.6.9-jamal/ip/iplink.c 2004-09-10 18:43:04.000000000 +0200 @@ -25,7 +25,7 @@ #include <arpa/inet.h> #include <string.h> #include <sys/ioctl.h> -#include <linux/sockios.h> +#include <linux/rtnetlink.h> #include "rt_names.h" #include "utils.h" @@ -46,6 +46,9 @@ fprintf(stderr, " txqueuelen PACKETS |\n"); fprintf(stderr, " name NEWNAME |\n"); fprintf(stderr, " address LLADDR | broadcast LLADDR |\n"); +#ifdef IFLA_WEIGHT + fprintf(stderr, " weight WEIGHT |\n"); +#endif fprintf(stderr, " mtu MTU }\n"); fprintf(stderr, " ip link show [ DEVICE ]\n"); exit(-1); @@ -174,48 +177,6 @@ return 0; } -static int get_address(char *dev, int *htype) -{ - struct ifreq ifr; - struct sockaddr_ll me; - int alen; - int s; - - s = socket(PF_PACKET, SOCK_DGRAM, 0); - if (s < 0) { - perror("socket(PF_PACKET)"); - return -1; - } - - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, dev); - if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { - perror("SIOCGIFINDEX"); - close(s); - return -1; - } - - memset(&me, 0, sizeof(me)); - me.sll_family = AF_PACKET; - me.sll_ifindex = ifr.ifr_ifindex; - me.sll_protocol = htons(ETH_P_LOOP); - if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) { - perror("bind"); - close(s); - return -1; - } - - alen = sizeof(me); - if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) { - perror("getsockname"); - close(s); - return -1; - } - close(s); - *htype = me.sll_hatype; - return me.sll_halen; -} - static int parse_address(char *dev, int hatype, int halen, char *lla, struct ifreq *ifr) { int alen; @@ -223,7 +184,7 @@ memset(ifr, 0, sizeof(*ifr)); strcpy(ifr->ifr_name, dev); ifr->ifr_hwaddr.sa_family = hatype; - alen = ll_addr_a2n(ifr->ifr_hwaddr.sa_data, 14, lla); + alen = ll_addr_a2n(ifr->ifr_hwaddr.sa_data, ADDRBUFSIZ, lla); if (alen < 0) return -1; if (alen != halen) { @@ -249,19 +210,46 @@ return 0; } +struct link_request +{ + struct nlmsghdr nl_msg; + struct ifinfomsg ifi; + char buf[256]; +}; + +#define USE_IOCTL_MTU 1 +#define USE_IOCTL_TXQLEN 2 +#define USE_IOCTL_FLAGS 4 +#define USE_IOCTL_NAME 8 +#define USE_IOCTL_ADDR 16 +#define USE_IOCTL_BRD 32 static int do_set(int argc, char **argv) { char *dev = NULL; __u32 mask = 0; __u32 flags = 0; - int qlen = -1; - int mtu = -1; + int32_t qlen = -1; + int32_t mtu = -1; + int32_t weight = -1; char *newaddr = NULL; char *newbrd = NULL; struct ifreq ifr0, ifr1; char *newname = NULL; int htype, halen; + struct rtnl_handle rth; + int use_ioctl_mask = 0; + + struct link_request req = { + .nl_msg = { + .nlmsg_type = RTM_SETLINK, + .nlmsg_flags = NLM_F_REQUEST, + .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), + }, + .ifi = { + .ifi_family = PF_PACKET, + }, + }; while (argc > 0) { if (strcmp(*argv, "up") == 0) { @@ -288,12 +276,22 @@ duparg("txqueuelen", *argv); if (get_integer(&qlen, *argv, 0)) invarg("Invalid \"txqueuelen\" value\n", *argv); +#ifdef IFLA_TXQLEN + addattr_l(&req.nl_msg, sizeof(req), IFLA_TXQLEN, &qlen, sizeof(qlen)); +#else + use_ioctl_mask |= USE_IOCTL_TXQLEN; +#endif } else if (strcmp(*argv, "mtu") == 0) { NEXT_ARG(); if (mtu != -1) duparg("mtu", *argv); if (get_integer(&mtu, *argv, 0)) invarg("Invalid \"mtu\" value\n", *argv); +#ifdef IFLA_MTU + addattr_l(&req.nl_msg, sizeof(req), IFLA_MTU, &mtu, sizeof(mtu)); +#else + use_ioctl_mask |= USE_IOCTL_MTU; +#endif } else if (strcmp(*argv, "multicast") == 0) { NEXT_ARG(); mask |= IFF_MULTICAST; @@ -339,6 +337,15 @@ flags |= IFF_NOARP; } else return on_off("noarp"); +#ifdef IFLA_WEIGHT + } else if (matches(*argv, "weight") == 0) { + NEXT_ARG(); + if (weight != -1) + duparg("weight", *argv); + if (get_integer(&weight, *argv, 0)) + invarg("Invalid \"weight\" value\n", *argv); + addattr_l(&req.nl_msg, sizeof(req), IFLA_WEIGHT, &weight, sizeof(weight)); +#endif #ifdef IFF_DYNAMIC } else if (matches(*argv, "dynamic") == 0) { NEXT_ARG(); @@ -367,20 +374,85 @@ fprintf(stderr, "Not enough of information: \"dev\" argument is required.\n"); exit(-1); } + + if (rtnl_open(&rth, 0) < 0) + exit(1); + + ll_init_map(&rth); + + if ((req.ifi.ifi_index = ll_name_to_index(dev)) == 0) { + fprintf(stderr, "Cannot find device \"%s\"\n", dev); + return -1; + } + + if (mask) { + req.ifi.ifi_flags = ll_index_to_flags(req.ifi.ifi_index); + if ((req.ifi.ifi_flags ^ flags) & mask) { + req.ifi.ifi_flags &= ~mask; + req.ifi.ifi_flags |= mask & flags; + } + } if (newaddr || newbrd) { - halen = get_address(dev, &htype); + halen = ll_index_to_alen(req.ifi.ifi_index); + htype = ll_index_to_type(req.ifi.ifi_index); + if (halen < 0) return -1; + if (newaddr) { if (parse_address(dev, htype, halen, newaddr, &ifr0) < 0) return -1; + + addattr_l(&req.nl_msg, sizeof(req), IFLA_ADDRESS, ifr0.ifr_hwaddr.sa_data, halen); } + if (newbrd) { if (parse_address(dev, htype, halen, newbrd, &ifr1) < 0) return -1; + addattr_l(&req.nl_msg, sizeof(req), IFLA_BROADCAST, ifr1.ifr_hwaddr.sa_data, halen); } } + + if (newname && strcmp(dev, newname)) { + char ifname[IFNAMSIZ] = {0}; + + strncpy(ifname, newname, sizeof(ifname) - 1); + addattr_l(&req.nl_msg, sizeof(req), IFLA_IFNAME, ifname, + strlen(ifname) + 1); + } + + if (rtnl_talk(&rth, &req.nl_msg, 0, 0, NULL, NULL, NULL) == 0) + { + /* successful but check if everything is implemented */ + ll_init_map(&rth); + + if (mask) + if ((ll_index_to_flags(req.ifi.ifi_index) ^ flags) & mask) + use_ioctl_mask |= USE_IOCTL_FLAGS; + + if (newaddr) + if (memcmp(ifr0.ifr_hwaddr.sa_data, + ll_index_to_addr(req.ifi.ifi_index), + ll_index_to_alen(req.ifi.ifi_index))) + use_ioctl_mask |= USE_IOCTL_ADDR; + + if (newbrd) + if (memcmp(ifr1.ifr_hwaddr.sa_data, + ll_index_to_brd(req.ifi.ifi_index), + ll_index_to_alen(req.ifi.ifi_index))) + use_ioctl_mask |= USE_IOCTL_BRD; + + if (newname && strcmp(dev, newname)) + if (strcmp(newname, ll_index_to_name(req.ifi.ifi_index))) + use_ioctl_mask |= USE_IOCTL_NAME; + + if (use_ioctl_mask == 0) + return 0; + } + + printf("rtnetlink method failed, trying ioctl...\n"); + /* rtnetlink method failed, try ioctl */ if (newname && strcmp(dev, newname)) { if (do_changename(dev, newname) < 0) @@ -407,6 +479,7 @@ } if (mask) return do_chflags(dev, flags, mask); + return 0; } diff -Nru iproute2-2.6.9-jamal.orig/lib/ll_map.c iproute2-2.6.9-jamal/lib/ll_map.c --- iproute2-2.6.9-jamal.orig/lib/ll_map.c 2004-09-08 19:23:18.000000000 +0200 +++ iproute2-2.6.9-jamal/lib/ll_map.c 2004-09-10 18:33:53.000000000 +0200 @@ -29,7 +29,8 @@ int type; int alen; unsigned flags; - unsigned char addr[8]; + unsigned char addr[ADDRBUFSIZ]; + unsigned char brd[ADDRBUFSIZ]; char name[16]; }; @@ -74,6 +75,10 @@ if (tb[IFLA_ADDRESS]) { int alen; im->alen = alen = RTA_PAYLOAD(tb[IFLA_ADDRESS]); + if (alen > ADDRBUFSIZ) { + fprintf(stderr, "Increase ADDRBUFSIZ\n"); + return -1; + } if (alen > sizeof(im->addr)) alen = sizeof(im->addr); memcpy(im->addr, RTA_DATA(tb[IFLA_ADDRESS]), alen); @@ -81,6 +86,17 @@ im->alen = 0; memset(im->addr, 0, sizeof(im->addr)); } + if (tb[IFLA_BROADCAST]) { + int alen = RTA_PAYLOAD(tb[IFLA_BROADCAST]); + if (alen > ADDRBUFSIZ) { + fprintf(stderr, "Increase ADDRBUFSIZ\n"); + return -1; + } + if (alen != im->alen) + return -1; + memcpy(im->brd, RTA_DATA(tb[IFLA_BROADCAST]), alen); + } else + memset(im->brd, 0, sizeof(im->brd)); strcpy(im->name, RTA_DATA(tb[IFLA_IFNAME])); return 0; } @@ -118,6 +134,42 @@ return -1; } +int ll_index_to_alen(int idx) +{ + struct idxmap *im; + + if (idx == 0) + return -1; + for (im = idxmap[idx&0xF]; im; im = im->next) + if (im->index == idx) + return im->alen; + return -1; +} + +unsigned char * ll_index_to_addr(int idx) +{ + struct idxmap *im; + + if (idx == 0) + return NULL; + for (im = idxmap[idx&0xF]; im; im = im->next) + if (im->index == idx) + return im->addr; + return NULL; +} + +unsigned char * ll_index_to_brd(int idx) +{ + struct idxmap *im; + + if (idx == 0) + return NULL; + for (im = idxmap[idx&0xF]; im; im = im->next) + if (im->index == idx) + return im->brd; + return NULL; +} + unsigned ll_index_to_flags(int idx) { struct idxmap *im; ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: iproute2 patch introducing mtu/txqlen/weight via rtnetlink 2004-09-10 13:16 ` jamal 2004-09-10 16:55 ` Thomas Graf @ 2004-09-10 21:14 ` David S. Miller 1 sibling, 0 replies; 9+ messages in thread From: David S. Miller @ 2004-09-10 21:14 UTC (permalink / raw) To: hadi; +Cc: shemminger, tgraf, yoshfuji, eric.lemoine, netdev On 10 Sep 2004 09:16:46 -0400 jamal <hadi@cyberus.ca> wrote: > > On Fri, 2004-09-10 at 05:40, Stephen Hemminger wrote: > > Unless there is some compelling reason, I think that keeping the old ioctl > > interface for a least a year until the kernel changes become more ubiquitous. > > I think that iproute2 should first attempt to use netlink and on failure > switch to ioctls. This is what I would recommend too. ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2004-09-10 21:14 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2004-09-09 16:48 iproute2 patch introducing mtu/txqlen/weight via rtnetlink Thomas Graf 2004-09-09 17:33 ` David S. Miller 2004-09-09 17:54 ` Thomas Graf 2004-09-10 1:33 ` YOSHIFUJI Hideaki / 吉藤英明 2004-09-10 9:29 ` Thomas Graf 2004-09-10 9:40 ` Stephen Hemminger 2004-09-10 13:16 ` jamal 2004-09-10 16:55 ` Thomas Graf 2004-09-10 21:14 ` David S. Miller
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).