* 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).