X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=include%2Fnet%2Fipv6.h;h=ccab5946c830da21409190aac9b854f0f905264a;hb=f013574014816c7a557b3c52233f3620463f0b9b;hp=31b3f1b45a2bfd1479bd685224e2a22238aa2ee6;hpb=14878f75abd5bf1d38becb405801cd491ee215dc;p=safe%2Fjmp%2Flinux-2.6 diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 31b3f1b..ccab594 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -4,8 +4,6 @@ * Authors: * Pedro Roque * - * $Id: ipv6.h,v 1.1 2002/05/20 15:13:07 jgrimm Exp $ - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version @@ -109,63 +107,60 @@ struct frag_hdr { #include /* sysctls */ -extern int sysctl_ipv6_bindv6only; extern int sysctl_mld_max_msf; +extern struct ctl_path net_ipv6_ctl_path[]; -#define _DEVINC(statname, modifier, idev, field) \ +#define _DEVINC(net, statname, modifier, idev, field) \ ({ \ struct inet6_dev *_idev = (idev); \ if (likely(_idev != NULL)) \ SNMP_INC_STATS##modifier((_idev)->stats.statname, (field)); \ - SNMP_INC_STATS##modifier(statname##_statistics, (field)); \ + SNMP_INC_STATS##modifier((net)->mib.statname##_statistics, (field));\ }) -/* MIBs */ -DECLARE_SNMP_STAT(struct ipstats_mib, ipv6_statistics); - -#define IP6_INC_STATS(idev,field) _DEVINC(ipv6, , idev, field) -#define IP6_INC_STATS_BH(idev,field) _DEVINC(ipv6, _BH, idev, field) -#define IP6_INC_STATS_USER(idev,field) _DEVINC(ipv6, _USER, idev, field) - -DECLARE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics); -DECLARE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics); - -#define ICMP6_INC_STATS(idev, field) _DEVINC(icmpv6, , idev, field) -#define ICMP6_INC_STATS_BH(idev, field) _DEVINC(icmpv6, _BH, idev, field) -#define ICMP6_INC_STATS_USER(idev, field) _DEVINC(icmpv6, _USER, idev, field) +#define _DEVADD(net, statname, modifier, idev, field, val) \ +({ \ + struct inet6_dev *_idev = (idev); \ + if (likely(_idev != NULL)) \ + SNMP_ADD_STATS##modifier((_idev)->stats.statname, (field), (val)); \ + SNMP_ADD_STATS##modifier((net)->mib.statname##_statistics, (field), (val));\ +}) -#define ICMP6_INC_STATS_OFFSET_BH(idev, field, offset) ({ \ - struct inet6_dev *_idev = idev; \ - __typeof__(offset) _offset = (offset); \ - if (likely(_idev != NULL)) \ - SNMP_INC_STATS_OFFSET_BH(_idev->stats.icmpv6, field, _offset); \ - SNMP_INC_STATS_OFFSET_BH(icmpv6_statistics, field, _offset); \ +#define _DEVUPD(net, statname, modifier, idev, field, val) \ +({ \ + struct inet6_dev *_idev = (idev); \ + if (likely(_idev != NULL)) \ + SNMP_UPD_PO_STATS##modifier((_idev)->stats.statname, field, (val)); \ + SNMP_UPD_PO_STATS##modifier((net)->mib.statname##_statistics, field, (val));\ }) -#define ICMP6MSGOUT_INC_STATS(idev, field) \ - _DEVINC(icmpv6msg, , idev, field +256) -#define ICMP6MSGOUT_INC_STATS_BH(idev, field) \ - _DEVINC(icmpv6msg, _BH, idev, field +256) -#define ICMP6MSGOUT_INC_STATS_USER(idev, field) \ - _DEVINC(icmpv6msg, _USER, idev, field +256) -#define ICMP6MSGIN_INC_STATS(idev, field) \ - _DEVINC(icmpv6msg, , idev, field) -#define ICMP6MSGIN_INC_STATS_BH(idev, field) \ - _DEVINC(icmpv6msg, _BH, idev, field) -#define ICMP6MSGIN_INC_STATS_USER(idev, field) \ - _DEVINC(icmpv6msg, _USER, idev, field) - -DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6); -DECLARE_SNMP_STAT(struct udp_mib, udplite_stats_in6); -#define UDP6_INC_STATS_BH(field, is_udplite) do { \ - if (is_udplite) SNMP_INC_STATS_BH(udplite_stats_in6, field); \ - else SNMP_INC_STATS_BH(udp_stats_in6, field); } while(0) -#define UDP6_INC_STATS_USER(field, is_udplite) do { \ - if (is_udplite) SNMP_INC_STATS_USER(udplite_stats_in6, field); \ - else SNMP_INC_STATS_USER(udp_stats_in6, field); } while(0) - -struct ip6_ra_chain -{ +/* MIBs */ + +#define IP6_INC_STATS(net, idev,field) \ + _DEVINC(net, ipv6, , idev, field) +#define IP6_INC_STATS_BH(net, idev,field) \ + _DEVINC(net, ipv6, _BH, idev, field) +#define IP6_ADD_STATS(net, idev,field,val) \ + _DEVADD(net, ipv6, , idev, field, val) +#define IP6_ADD_STATS_BH(net, idev,field,val) \ + _DEVADD(net, ipv6, _BH, idev, field, val) +#define IP6_UPD_PO_STATS(net, idev,field,val) \ + _DEVUPD(net, ipv6, , idev, field, val) +#define IP6_UPD_PO_STATS_BH(net, idev,field,val) \ + _DEVUPD(net, ipv6, _BH, idev, field, val) +#define ICMP6_INC_STATS(net, idev, field) \ + _DEVINC(net, icmpv6, , idev, field) +#define ICMP6_INC_STATS_BH(net, idev, field) \ + _DEVINC(net, icmpv6, _BH, idev, field) + +#define ICMP6MSGOUT_INC_STATS(net, idev, field) \ + _DEVINC(net, icmpv6msg, , idev, field +256) +#define ICMP6MSGOUT_INC_STATS_BH(net, idev, field) \ + _DEVINC(net, icmpv6msg, _BH, idev, field +256) +#define ICMP6MSGIN_INC_STATS_BH(net, idev, field) \ + _DEVINC(net, icmpv6msg, _BH, idev, field) + +struct ip6_ra_chain { struct ip6_ra_chain *next; struct sock *sk; int sel; @@ -180,8 +175,7 @@ extern rwlock_t ip6_ra_lock; ancillary data and passed to IPv6. */ -struct ipv6_txoptions -{ +struct ipv6_txoptions { /* Length of this structure */ int tot_len; @@ -198,8 +192,7 @@ struct ipv6_txoptions /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */ }; -struct ip6_flowlabel -{ +struct ip6_flowlabel { struct ip6_flowlabel *next; __be32 label; atomic_t users; @@ -210,13 +203,13 @@ struct ip6_flowlabel u32 owner; unsigned long lastuse; unsigned long expires; + struct net *fl_net; }; -#define IPV6_FLOWINFO_MASK __constant_htonl(0x0FFFFFFF) -#define IPV6_FLOWLABEL_MASK __constant_htonl(0x000FFFFF) +#define IPV6_FLOWINFO_MASK cpu_to_be32(0x0FFFFFFF) +#define IPV6_FLOWLABEL_MASK cpu_to_be32(0x000FFFFF) -struct ipv6_fl_socklist -{ +struct ipv6_fl_socklist { struct ipv6_fl_socklist *next; struct ip6_flowlabel *fl; }; @@ -227,7 +220,7 @@ extern struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_spac struct ipv6_txoptions * fopt); extern void fl6_free_socklist(struct sock *sk); extern int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen); -extern void ip6_flowlabel_init(void); +extern int ip6_flowlabel_init(void); extern void ip6_flowlabel_cleanup(void); static inline void fl6_sock_release(struct ip6_flowlabel *fl) @@ -236,11 +229,9 @@ static inline void fl6_sock_release(struct ip6_flowlabel *fl) atomic_dec(&fl->users); } -extern int ip6_ra_control(struct sock *sk, int sel, - void (*destructor)(struct sock *)); +extern int ip6_ra_control(struct sock *sk, int sel); - -extern int ipv6_parse_hopopts(struct sk_buff **skbp); +extern int ipv6_parse_hopopts(struct sk_buff *skb); extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt); extern struct ipv6_txoptions * ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, @@ -252,20 +243,11 @@ struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space, extern int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb); -extern int ip6_frag_nqueues; -extern atomic_t ip6_frag_mem; +int ip6_frag_nqueues(struct net *net); +int ip6_frag_mem(struct net *net); #define IPV6_FRAG_TIMEOUT (60*HZ) /* 60 seconds */ -/* - * Function prototype for build_xmit - */ - -typedef int (*inet_getfrag_t) (const void *data, - struct in6_addr *addr, - char *, - unsigned int, unsigned int); - extern int __ipv6_addr_type(const struct in6_addr *addr); static inline int ipv6_addr_type(const struct in6_addr *addr) { @@ -296,12 +278,10 @@ static inline int ipv6_masked_addr_cmp(const struct in6_addr *a1, const struct in6_addr *m, const struct in6_addr *a2) { - unsigned int i; - - for (i = 0; i < 4; i++) - if ((a1->s6_addr32[i] ^ a2->s6_addr32[i]) & m->s6_addr32[i]) - return 1; - return 0; + return (!!(((a1->s6_addr32[0] ^ a2->s6_addr32[0]) & m->s6_addr32[0]) | + ((a1->s6_addr32[1] ^ a2->s6_addr32[1]) & m->s6_addr32[1]) | + ((a1->s6_addr32[2] ^ a2->s6_addr32[2]) & m->s6_addr32[2]) | + ((a1->s6_addr32[3] ^ a2->s6_addr32[3]) & m->s6_addr32[3]))); } static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2) @@ -336,10 +316,10 @@ static inline void ipv6_addr_set(struct in6_addr *addr, static inline int ipv6_addr_equal(const struct in6_addr *a1, const struct in6_addr *a2) { - return (a1->s6_addr32[0] == a2->s6_addr32[0] && - a1->s6_addr32[1] == a2->s6_addr32[1] && - a1->s6_addr32[2] == a2->s6_addr32[2] && - a1->s6_addr32[3] == a2->s6_addr32[3]); + return (((a1->s6_addr32[0] ^ a2->s6_addr32[0]) | + (a1->s6_addr32[1] ^ a2->s6_addr32[1]) | + (a1->s6_addr32[2] ^ a2->s6_addr32[2]) | + (a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0); } static inline int __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2, @@ -368,16 +348,60 @@ static inline int ipv6_prefix_equal(const struct in6_addr *a1, prefixlen); } +struct inet_frag_queue; + +enum ip6_defrag_users { + IP6_DEFRAG_LOCAL_DELIVER, + IP6_DEFRAG_CONNTRACK_IN, + IP6_DEFRAG_CONNTRACK_OUT, + IP6_DEFRAG_CONNTRACK_BRIDGE_IN, +}; + +struct ip6_create_arg { + __be32 id; + u32 user; + struct in6_addr *src; + struct in6_addr *dst; +}; + +void ip6_frag_init(struct inet_frag_queue *q, void *a); +int ip6_frag_match(struct inet_frag_queue *q, void *a); + static inline int ipv6_addr_any(const struct in6_addr *a) { return ((a->s6_addr32[0] | a->s6_addr32[1] | a->s6_addr32[2] | a->s6_addr32[3] ) == 0); } +static inline int ipv6_addr_loopback(const struct in6_addr *a) +{ + return ((a->s6_addr32[0] | a->s6_addr32[1] | + a->s6_addr32[2] | (a->s6_addr32[3] ^ htonl(1))) == 0); +} + static inline int ipv6_addr_v4mapped(const struct in6_addr *a) { - return ((a->s6_addr32[0] | a->s6_addr32[1]) == 0 && - a->s6_addr32[2] == htonl(0x0000ffff)); + return ((a->s6_addr32[0] | a->s6_addr32[1] | + (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0); +} + +/* + * Check for a RFC 4843 ORCHID address + * (Overlay Routable Cryptographic Hash Identifiers) + */ +static inline int ipv6_addr_orchid(const struct in6_addr *a) +{ + return ((a->s6_addr32[0] & htonl(0xfffffff0)) + == htonl(0x20010010)); +} + +static inline void ipv6_addr_set_v4mapped(const __be32 addr, + struct in6_addr *v4mapped) +{ + ipv6_addr_set(v4mapped, + 0, 0, + htonl(0x0000FFFF), + addr); } /* @@ -421,6 +445,18 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr)); } +static __inline__ void ipv6_select_ident(struct frag_hdr *fhdr) +{ + static u32 ipv6_fragmentation_id = 1; + static DEFINE_SPINLOCK(ip6_id_lock); + + spin_lock_bh(&ip6_id_lock); + fhdr->identification = htonl(ipv6_fragmentation_id); + if (++ipv6_fragmentation_id == 0) + ipv6_fragmentation_id = 1; + spin_unlock_bh(&ip6_id_lock); +} + /* * Prototypes exported by ipv6 */ @@ -448,8 +484,8 @@ extern int ip6_xmit(struct sock *sk, extern int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev, - struct in6_addr *saddr, - struct in6_addr *daddr, + const struct in6_addr *saddr, + const struct in6_addr *daddr, int proto, int len); extern int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr); @@ -489,18 +525,13 @@ extern int ip6_forward(struct sk_buff *skb); extern int ip6_input(struct sk_buff *skb); extern int ip6_mc_input(struct sk_buff *skb); +extern int __ip6_local_out(struct sk_buff *skb); +extern int ip6_local_out(struct sk_buff *skb); + /* * Extension header (options) processing */ -extern u8 * ipv6_build_nfrag_opts(struct sk_buff *skb, - u8 *prev_hdr, - struct ipv6_txoptions *opt, - struct in6_addr *daddr, - u32 jumbolen); -extern u8 * ipv6_build_frag_opts(struct sk_buff *skb, - u8 *prev_hdr, - struct ipv6_txoptions *opt); extern void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto, @@ -523,7 +554,7 @@ extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type); extern int ipv6_setsockopt(struct sock *sk, int level, int optname, char __user *optval, - int optlen); + unsigned int optlen); extern int ipv6_getsockopt(struct sock *sk, int level, int optname, char __user *optval, @@ -532,17 +563,13 @@ extern int compat_ipv6_setsockopt(struct sock *sk, int level, int optname, char __user *optval, - int optlen); + unsigned int optlen); extern int compat_ipv6_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); -extern void ipv6_packet_init(void); - -extern void ipv6_packet_cleanup(void); - extern int ip6_datagram_connect(struct sock *sk, struct sockaddr *addr, int addr_len); @@ -565,11 +592,6 @@ extern int inet6_hash_connect(struct inet_timewait_death_row *death_row, /* * reassembly.c */ -extern int sysctl_ip6frag_high_thresh; -extern int sysctl_ip6frag_low_thresh; -extern int sysctl_ip6frag_time; -extern int sysctl_ip6frag_secret_interval; - extern const struct proto_ops inet6_stream_ops; extern const struct proto_ops inet6_dgram_ops; @@ -582,16 +604,18 @@ extern int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf); extern int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf, struct group_filter __user *optval, int __user *optlen); +extern unsigned int inet6_hash_frag(__be32 id, const struct in6_addr *saddr, + const struct in6_addr *daddr, u32 rnd); #ifdef CONFIG_PROC_FS -extern int ac6_proc_init(void); -extern void ac6_proc_exit(void); +extern int ac6_proc_init(struct net *net); +extern void ac6_proc_exit(struct net *net); extern int raw6_proc_init(void); extern void raw6_proc_exit(void); -extern int tcp6_proc_init(void); -extern void tcp6_proc_exit(void); -extern int udp6_proc_init(void); -extern void udp6_proc_exit(void); +extern int tcp6_proc_init(struct net *net); +extern void tcp6_proc_exit(struct net *net); +extern int udp6_proc_init(struct net *net); +extern void udp6_proc_exit(struct net *net); extern int udplite6_proc_init(void); extern void udplite6_proc_exit(void); extern int ipv6_misc_proc_init(void); @@ -599,25 +623,23 @@ extern void ipv6_misc_proc_exit(void); extern int snmp6_register_dev(struct inet6_dev *idev); extern int snmp6_unregister_dev(struct inet6_dev *idev); -extern struct rt6_statistics rt6_stats; #else -static inline int snmp6_register_dev(struct inet6_dev *idev) -{ - return 0; -} - -static inline int snmp6_unregister_dev(struct inet6_dev *idev) -{ - return 0; -} +static inline int ac6_proc_init(struct net *net) { return 0; } +static inline void ac6_proc_exit(struct net *net) { } +static inline int snmp6_register_dev(struct inet6_dev *idev) { return 0; } +static inline int snmp6_unregister_dev(struct inet6_dev *idev) { return 0; } #endif #ifdef CONFIG_SYSCTL -extern ctl_table ipv6_route_table[]; -extern ctl_table ipv6_icmp_table[]; +extern ctl_table ipv6_route_table_template[]; +extern ctl_table ipv6_icmp_table_template[]; -extern void ipv6_sysctl_register(void); +extern struct ctl_table *ipv6_icmp_sysctl_init(struct net *net); +extern struct ctl_table *ipv6_route_sysctl_init(struct net *net); +extern int ipv6_sysctl_register(void); extern void ipv6_sysctl_unregister(void); +extern int ipv6_static_sysctl_register(void); +extern void ipv6_static_sysctl_unregister(void); #endif #endif /* __KERNEL__ */