#include <linux/netlink.h>
#include <linux/if_link.h>
+#include <linux/if_addr.h>
+#include <linux/neighbour.h>
/****
* Routing/neighbour discovery messages.
RTA_FLOW,
RTA_CACHEINFO,
RTA_SESSION,
- RTA_MP_ALGO,
+ RTA_MP_ALGO, /* no longer used */
RTA_TABLE,
__RTA_MAX
};
}
extern int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len);
+extern int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+ struct rtattr *rta, int len);
#define rtattr_parse_nested(tb, max, rta) \
rtattr_parse((tb), (max), RTA_DATA((rta)), RTA_PAYLOAD((rta)))
-struct rtnetlink_link
-{
- int (*doit)(struct sk_buff *, struct nlmsghdr*, void *attr);
- int (*dumpit)(struct sk_buff *, struct netlink_callback *cb);
-};
+#define rtattr_parse_nested_compat(tb, max, rta, data, len) \
+({ data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
+ __rtattr_parse_nested_compat(tb, max, rta, len); })
-extern struct rtnetlink_link * rtnetlink_links[NPROTO];
extern int rtnetlink_send(struct sk_buff *skb, u32 pid, u32 group, int echo);
extern int rtnl_unicast(struct sk_buff *skb, u32 pid);
extern int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
#define RTA_PUT_NOHDR(skb, attrlen, data) \
({ RTA_APPEND(skb, RTA_ALIGN(attrlen), data); \
- memset(skb->tail - (RTA_ALIGN(attrlen) - attrlen), 0, \
+ memset(skb_tail_pointer(skb) - (RTA_ALIGN(attrlen) - attrlen), 0, \
RTA_ALIGN(attrlen) - attrlen); })
#define RTA_PUT_U8(skb, attrtype, value) \
RTA_PUT(skb, attrtype, 0, NULL);
#define RTA_NEST(skb, type) \
-({ struct rtattr *__start = (struct rtattr *) (skb)->tail; \
+({ struct rtattr *__start = (struct rtattr *)skb_tail_pointer(skb); \
RTA_PUT(skb, type, 0, NULL); \
__start; })
#define RTA_NEST_END(skb, start) \
-({ (start)->rta_len = ((skb)->tail - (unsigned char *) (start)); \
+({ (start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
+ (skb)->len; })
+
+#define RTA_NEST_COMPAT(skb, type, attrlen, data) \
+({ struct rtattr *__start = (struct rtattr *)skb_tail_pointer(skb); \
+ RTA_PUT(skb, type, attrlen, data); \
+ RTA_NEST(skb, type); \
+ __start; })
+
+#define RTA_NEST_COMPAT_END(skb, start) \
+({ struct rtattr *__nest = (void *)(start) + NLMSG_ALIGN((start)->rta_len); \
+ (start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
+ RTA_NEST_END(skb, __nest); \
(skb)->len; })
#define RTA_NEST_CANCEL(skb, start) \