diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/config.h pfinet6/config.h --- pfinet-after-import/config.h 2007-10-07 01:30:31.000000000 +0200 +++ pfinet6/config.h 2007-10-07 01:21:41.000000000 +0200 @@ -7,6 +7,7 @@ #define CONFIG_NET 1 #define CONFIG_INET 1 +#define CONFIG_IPV6 1 #undef CONFIG_IPX #undef CONFIG_ATALK @@ -34,3 +35,6 @@ #define CONFIG_SKB_LARGE 1 #define CONFIG_IP_NOSIOCRT 1 /* How convenient. */ + +#define CONFIG_IPV6_EUI64 1 +#undef CONFIG_IPV6_NO_PB diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/ethernet.c pfinet6/ethernet.c --- pfinet-after-import/ethernet.c 2007-10-07 01:30:31.000000000 +0200 +++ pfinet6/ethernet.c 2007-10-07 01:21:41.000000000 +0200 @@ -119,7 +119,7 @@ ethernet_demuxer (mach_msg_header_t *inp __mutex_lock (&net_bh_lock); skb = alloc_skb (datalen, GFP_ATOMIC); - skb->len = datalen; + skb_put (skb, datalen); skb->dev = dev; /* Copy the two parts of the frame into the buffer. */ diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/glue-include/asm/delay.h pfinet6/glue-include/asm/delay.h --- pfinet-after-import/glue-include/asm/delay.h 1970-01-01 01:00:00.000000000 +0100 +++ pfinet6/glue-include/asm/delay.h 2007-10-07 01:21:41.000000000 +0200 @@ -0,0 +1 @@ +/* stub file. */ diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/glue-include/linux/in6.h pfinet6/glue-include/linux/in6.h --- pfinet-after-import/glue-include/linux/in6.h 2007-10-07 01:30:31.000000000 +0200 +++ pfinet6/glue-include/linux/in6.h 2007-10-07 01:21:41.000000000 +0200 @@ -1 +1,110 @@ +#ifndef GLUE_LINUX_IN6_H +#define GLUE_LINUX_IN6_H 1 + #include + +#if 0 +struct ipv6_mreq { + /* IPv6 multicast address of group */ + struct in6_addr ipv6mr_multiaddr; + + /* local IPv6 address of interface */ + int ipv6mr_ifindex; +}; +#endif + +/* In Linux's struct ipv6_mreq the second member is called ipv6mr_ifindex, + * however it's called ipv6mr_interface in ours. + */ +#define ipv6mr_ifindex ipv6mr_interface + +struct in6_flowlabel_req +{ + struct in6_addr flr_dst; + __u32 flr_label; + __u8 flr_action; + __u8 flr_share; + __u16 flr_flags; + __u16 flr_expires; + __u16 flr_linger; + __u32 __flr_pad; + /* Options in format of IPV6_PKTOPTIONS */ +}; + +#define IPV6_FL_A_GET 0 +#define IPV6_FL_A_PUT 1 +#define IPV6_FL_A_RENEW 2 + +#define IPV6_FL_F_CREATE 1 +#define IPV6_FL_F_EXCL 2 + +#define IPV6_FL_S_NONE 0 +#define IPV6_FL_S_EXCL 1 +#define IPV6_FL_S_PROCESS 2 +#define IPV6_FL_S_USER 3 +#define IPV6_FL_S_ANY 255 + + +/* + * Bitmask constant declarations to help applications select out the + * flow label and priority fields. + * + * Note that this are in host byte order while the flowinfo field of + * sockaddr_in6 is in network byte order. + */ + +#define IPV6_FLOWINFO_FLOWLABEL 0x000fffff +#define IPV6_FLOWINFO_PRIORITY 0x0ff00000 + +/* These defintions are obsolete */ +#define IPV6_PRIORITY_UNCHARACTERIZED 0x0000 +#define IPV6_PRIORITY_FILLER 0x0100 +#define IPV6_PRIORITY_UNATTENDED 0x0200 +#define IPV6_PRIORITY_RESERVED1 0x0300 +#define IPV6_PRIORITY_BULK 0x0400 +#define IPV6_PRIORITY_RESERVED2 0x0500 +#define IPV6_PRIORITY_INTERACTIVE 0x0600 +#define IPV6_PRIORITY_CONTROL 0x0700 +#define IPV6_PRIORITY_8 0x0800 +#define IPV6_PRIORITY_9 0x0900 +#define IPV6_PRIORITY_10 0x0a00 +#define IPV6_PRIORITY_11 0x0b00 +#define IPV6_PRIORITY_12 0x0c00 +#define IPV6_PRIORITY_13 0x0d00 +#define IPV6_PRIORITY_14 0x0e00 +#define IPV6_PRIORITY_15 0x0f00 + +/* + * IPv6 TLV options. + */ +#define IPV6_TLV_PAD0 0 +#define IPV6_TLV_PADN 1 +#define IPV6_TLV_ROUTERALERT 20 +#define IPV6_TLV_JUMBO 194 + +/* + * IPV6 socket options + */ + +#define IPV6_ADDRFORM 1 +#define IPV6_PKTINFO 2 +#define IPV6_HOPOPTS 3 +#define IPV6_DSTOPTS 4 +#define IPV6_RTHDR 5 +#define IPV6_PKTOPTIONS 6 +#define IPV6_CHECKSUM 7 +#define IPV6_HOPLIMIT 8 +#define IPV6_NEXTHOP 9 +#define IPV6_AUTHHDR 10 +#define IPV6_FLOWINFO 11 + +/* IPV6_MTU_DISCOVER values */ +#define IPV6_PMTUDISC_DONT 0 +#define IPV6_PMTUDISC_WANT 1 +#define IPV6_PMTUDISC_DO 2 + +/* Flowlabel */ +#define IPV6_FLOWLABEL_MGR 32 +#define IPV6_FLOWINFO_SEND 33 + +#endif /* not GLUE_LINUX_IN6_H */ diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/glue-include/linux/ipv6.h pfinet6/glue-include/linux/ipv6.h --- pfinet-after-import/glue-include/linux/ipv6.h 2007-10-07 01:30:31.000000000 +0200 +++ pfinet6/glue-include/linux/ipv6.h 2007-10-07 01:21:41.000000000 +0200 @@ -1 +1,117 @@ +#ifndef _IPV6_H +#define _IPV6_H + #include +#include + +/* The latest drafts declared increase in minimal mtu up to 1280. */ + +#define IPV6_MIN_MTU 1280 + +/* + * Advanced API + * source interface/address selection, source routing, etc... + * *under construction* + */ + + +struct in6_ifreq { + struct in6_addr ifr6_addr; + __u32 ifr6_prefixlen; + int ifr6_ifindex; +}; + +#define IPV6_SRCRT_STRICT 0x01 /* this hop must be a neighbor */ +#define IPV6_SRCRT_TYPE_0 0 /* IPv6 type 0 Routing Header */ + +/* + * routing header + */ +struct ipv6_rt_hdr { + __u8 nexthdr; + __u8 hdrlen; + __u8 type; + __u8 segments_left; + + /* + * type specific data + * variable length field + */ +}; + + +struct ipv6_opt_hdr { + __u8 nexthdr; + __u8 hdrlen; + /* + * TLV encoded option data follows. + */ +}; + +#define ipv6_destopt_hdr ipv6_opt_hdr +#define ipv6_hopopt_hdr ipv6_opt_hdr + +#ifdef __KERNEL__ +#define ipv6_optlen(p) (((p)->hdrlen+1) << 3) +#endif + +/* + * routing header type 0 (used in cmsghdr struct) + */ + +struct rt0_hdr { + struct ipv6_rt_hdr rt_hdr; + __u32 bitmap; /* strict/loose bit map */ + struct in6_addr addr[0]; + +#define rt0_type rt_hdr.type; +}; + +/* + * IPv6 fixed header + * + * BEWARE, it is incorrect. The first 4 bits of flow_lbl + * are glued to priority now, forming "class". + */ + +struct ipv6hdr { +#if defined(__LITTLE_ENDIAN_BITFIELD) + __u8 priority:4, + version:4; +#elif defined(__BIG_ENDIAN_BITFIELD) + __u8 version:4, + priority:4; +#else +#error "Please fix " +#endif + __u8 flow_lbl[3]; + + __u16 payload_len; + __u8 nexthdr; + __u8 hop_limit; + + struct in6_addr saddr; + struct in6_addr daddr; +}; + +#ifdef __KERNEL__ + +/* + This structure contains results of exthdrs parsing + as offsets from skb->nh. + */ + +struct inet6_skb_parm +{ + int iif; + __u16 ra; + __u16 hop; + __u16 auth; + __u16 dst0; + __u16 srcrt; + __u16 dst1; +}; + +#endif + +#endif diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/glue-include/linux/socket.h pfinet6/glue-include/linux/socket.h --- pfinet-after-import/glue-include/linux/socket.h 2007-10-07 01:30:31.000000000 +0200 +++ pfinet6/glue-include/linux/socket.h 2007-10-07 01:21:41.000000000 +0200 @@ -22,6 +22,8 @@ #define SOL_IP IPPROTO_IP #define SOL_TCP IPPROTO_TCP +#define SOL_IPV6 IPPROTO_IPV6 +#define SOL_ICMPV6 IPPROTO_ICMPV6 #define SOL_RAW IPPROTO_RAW /* IP options */ diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/linux-src/net/ipv6/addrconf.c pfinet6/linux-src/net/ipv6/addrconf.c --- pfinet-after-import/linux-src/net/ipv6/addrconf.c 2007-10-07 01:38:32.000000000 +0200 +++ pfinet6/linux-src/net/ipv6/addrconf.c 2007-10-07 01:21:41.000000000 +0200 @@ -247,7 +247,10 @@ static struct inet6_dev * ipv6_add_dev(s return ndev; } -static struct inet6_dev * ipv6_find_idev(struct device *dev) +#ifndef _HURD_ +static +#endif +struct inet6_dev * ipv6_find_idev(struct device *dev) { struct inet6_dev *idev; @@ -808,6 +811,7 @@ ok: } } +#ifndef _HURD_ /* * Set destination address. * Special case for SIT interfaces where we create a new "virtual" @@ -865,11 +869,15 @@ err_exit: rtnl_unlock(); return err; } +#endif /* not _HURD_ */ /* * Manual configuration of address on an interface */ -static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen) +#ifndef _HURD_ +static +#endif +int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen) { struct inet6_ifaddr *ifp; struct inet6_dev *idev; @@ -900,7 +908,10 @@ static int inet6_addr_add(int ifindex, s return -ENOBUFS; } -static int inet6_addr_del(int ifindex, struct in6_addr *pfx, int plen) +#ifndef _HURD_ +static +#endif +int inet6_addr_del(int ifindex, struct in6_addr *pfx, int plen) { struct inet6_ifaddr *ifp; struct inet6_dev *idev; @@ -932,6 +943,7 @@ static int inet6_addr_del(int ifindex, s } +#ifndef _HURD_ int addrconf_add_ifaddr(void *arg) { struct in6_ifreq ireq; @@ -948,7 +960,9 @@ int addrconf_add_ifaddr(void *arg) rtnl_unlock(); return err; } +#endif /* not _HURD_ */ +#ifndef _HURD_ int addrconf_del_ifaddr(void *arg) { struct in6_ifreq ireq; @@ -965,6 +979,7 @@ int addrconf_del_ifaddr(void *arg) rtnl_unlock(); return err; } +#endif /* not _HURD_ */ static void sit_add_v4_addrs(struct inet6_dev *idev) { diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/linux-src/net/ipv6/af_inet6.c pfinet6/linux-src/net/ipv6/af_inet6.c --- pfinet-after-import/linux-src/net/ipv6/af_inet6.c 2007-10-07 01:39:45.000000000 +0200 +++ pfinet6/linux-src/net/ipv6/af_inet6.c 2007-10-07 01:21:41.000000000 +0200 @@ -337,6 +337,10 @@ static int inet6_getname(struct socket * return(0); } +#ifdef _HURD_ +#define inet6_ioctl 0 +#else + static int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { struct sock *sk = sock->sk; @@ -396,6 +400,8 @@ static int inet6_ioctl(struct socket *so return(0); } +#endif /* not _HURD_ */ + struct proto_ops inet6_stream_ops = { PF_INET6, @@ -542,7 +548,9 @@ __initfunc(void inet6_proto_init(struct ip6_route_init(); ip6_flowlabel_init(); addrconf_init(); +#ifndef _HURD_ sit_init(); +#endif /* Init v6 transport protocols. */ udpv6_init(); diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/linux-src/net/ipv6/icmpv6.c pfinet6/linux-src/net/ipv6/icmpv6.c --- pfinet-after-import/linux-src/net/ipv6/icmpv6.c 2007-10-07 01:35:56.000000000 +0200 +++ pfinet6/linux-src/net/ipv6/icmpv6.c 2007-10-07 01:21:41.000000000 +0200 @@ -499,6 +499,7 @@ int icmpv6_rcv(struct sk_buff *skb, unsi } default: /* CHECKSUM_UNNECESSARY */ + break; }; /* @@ -600,8 +601,10 @@ int __init icmpv6_init(struct net_proto_ "Failed to create the ICMP6 control socket.\n"); return -1; } +#ifndef _HURD_ icmpv6_socket->inode->i_uid = 0; icmpv6_socket->inode->i_gid = 0; +#endif icmpv6_socket->type = SOCK_RAW; if ((err = ops->create(icmpv6_socket, IPPROTO_ICMPV6)) < 0) { diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/linux-src/net/ipv6/ip6_fib.c pfinet6/linux-src/net/ipv6/ip6_fib.c --- pfinet-after-import/linux-src/net/ipv6/ip6_fib.c 2007-10-07 01:37:28.000000000 +0200 +++ pfinet6/linux-src/net/ipv6/ip6_fib.c 2007-10-07 01:21:41.000000000 +0200 @@ -36,7 +36,7 @@ #undef CONFIG_IPV6_SUBTREES #if RT6_DEBUG >= 1 -#define BUG_TRAP(x) ({ if (!(x)) { printk("Assertion (" #x ") failed at " __FILE__ "(%d):" __FUNCTION__ "\n", __LINE__); } }) +#define BUG_TRAP(x) ({ if (!(x)) { printk("Assertion (" #x ") failed at " __FILE__ "(%d):%s\n", __LINE__, __FUNCTION__); } }) #else #define BUG_TRAP(x) do { ; } while (0) #endif @@ -94,7 +94,7 @@ static struct timer_list ip6_fib_timer = fib6_run_gc }; -static struct fib6_walker_t fib6_walker_list = { +struct fib6_walker_t fib6_walker_list = { &fib6_walker_list, &fib6_walker_list, }; diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/linux-src/net/ipv6/ip6_flowlabel.c pfinet6/linux-src/net/ipv6/ip6_flowlabel.c --- pfinet-after-import/linux-src/net/ipv6/ip6_flowlabel.c 2007-10-07 01:37:28.000000000 +0200 +++ pfinet6/linux-src/net/ipv6/ip6_flowlabel.c 2007-10-07 01:21:41.000000000 +0200 @@ -340,8 +340,15 @@ fl_create(struct in6_flowlabel_req *freq fl->owner = current->pid; break; case IPV6_FL_S_USER: +#ifdef _HURD_ + /* FIXME + * Which euid shall be assigned? Where to get it, + * `struct task_struct' doesn't have a `euid'. + */ +#else fl->owner = current->euid; break; +#endif default: err = -EINVAL; goto done; diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/linux-src/net/ipv6/mcast.c pfinet6/linux-src/net/ipv6/mcast.c --- pfinet-after-import/linux-src/net/ipv6/mcast.c 2007-10-07 01:33:21.000000000 +0200 +++ pfinet6/linux-src/net/ipv6/mcast.c 2007-10-07 01:21:41.000000000 +0200 @@ -671,8 +671,10 @@ __initfunc(int igmp6_init(struct net_pro "Failed to create the IGMP6 control socket.\n"); return -1; } +#ifndef _HURD_ igmp6_socket->inode->i_uid = 0; igmp6_socket->inode->i_gid = 0; +#endif igmp6_socket->type = SOCK_RAW; if((err = ops->create(igmp6_socket, IPPROTO_ICMPV6)) < 0) { diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/linux-src/net/ipv6/ndisc.c pfinet6/linux-src/net/ipv6/ndisc.c --- pfinet-after-import/linux-src/net/ipv6/ndisc.c 2007-10-07 01:35:37.000000000 +0200 +++ pfinet6/linux-src/net/ipv6/ndisc.c 2007-10-07 01:21:41.000000000 +0200 @@ -1164,8 +1164,10 @@ __initfunc(int ndisc_init(struct net_pro "Failed to create the NDISC control socket.\n"); return -1; } +#ifndef _HURD_ ndisc_socket->inode->i_uid = 0; ndisc_socket->inode->i_gid = 0; +#endif ndisc_socket->type = SOCK_RAW; if((err = ops->create(ndisc_socket, IPPROTO_ICMPV6)) < 0) { diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/linux-src/net/ipv6/route_ipv6.c pfinet6/linux-src/net/ipv6/route_ipv6.c --- pfinet-after-import/linux-src/net/ipv6/route_ipv6.c 2007-10-07 01:35:56.000000000 +0200 +++ pfinet6/linux-src/net/ipv6/route_ipv6.c 2007-10-07 01:21:41.000000000 +0200 @@ -1156,6 +1156,7 @@ restart: } } +#ifndef _HURD_ int ipv6_route_ioctl(unsigned int cmd, void *arg) { struct in6_rtmsg rtmsg; @@ -1194,6 +1195,7 @@ int ipv6_route_ioctl(unsigned int cmd, v return -EINVAL; } +#endif /* not _HURD_ */ /* * Drop the packet on the floor diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/linux-src/net/ipv6/tcp_ipv6.c pfinet6/linux-src/net/ipv6/tcp_ipv6.c --- pfinet-after-import/linux-src/net/ipv6/tcp_ipv6.c 2007-10-07 01:38:57.000000000 +0200 +++ pfinet6/linux-src/net/ipv6/tcp_ipv6.c 2007-10-07 01:21:41.000000000 +0200 @@ -103,7 +103,10 @@ static int tcp_v6_get_port(struct sock * if (tb->port == rover) goto next; break; + next: + (void) 0; + } while (--remaining > 0); tcp_port_rover = rover; @@ -1426,6 +1429,7 @@ int tcp_v6_rcv(struct sk_buff *skb, unsi } default: /* CHECKSUM_UNNECESSARY */ + break; }; if((th->doff * 4) < sizeof(struct tcphdr) || diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/linux-src/net/ipv6/udp_ipv6.c pfinet6/linux-src/net/ipv6/udp_ipv6.c --- pfinet-after-import/linux-src/net/ipv6/udp_ipv6.c 2007-10-07 01:39:03.000000000 +0200 +++ pfinet6/linux-src/net/ipv6/udp_ipv6.c 2007-10-07 01:21:41.000000000 +0200 @@ -79,7 +79,9 @@ static int udp_v6_get_port(struct sock * } while ((sk = sk->next) != NULL); best_size_so_far = size; best = result; + next: + (void) 0; } result = best; for(;; result += UDP_HTABLE_SIZE) { @@ -890,6 +892,10 @@ static struct inet6_protocol udpv6_proto "UDPv6" /* name */ }; +#ifdef _HURD_ +#define udp_ioctl 0 +#endif + struct proto udpv6_prot = { (struct sock *)&udpv6_prot, /* sklist_next */ (struct sock *)&udpv6_prot, /* sklist_prev */ diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/main.c pfinet6/main.c --- pfinet-after-import/main.c 2007-10-07 01:30:31.000000000 +0200 +++ pfinet6/main.c 2007-10-07 01:21:41.000000000 +0200 @@ -1,5 +1,5 @@ /* - Copyright (C) 1995,96,97,99,2000,02 Free Software Foundation, Inc. + Copyright (C) 1995,96,97,99,2000,02,07 Free Software Foundation, Inc. Written by Michael I. Bushnell, p/BSG. This file is part of the GNU Hurd. @@ -29,6 +29,11 @@ #include #include +/* Include Hurd's errno.h file, but don't include glue-include/hurd/errno.h, + since it #undef's the errno macro. */ +#define _HACK_ERRNO_H +#include + #include #include @@ -43,10 +48,15 @@ int trivfs_support_read = 1; int trivfs_support_write = 1; int trivfs_support_exec = 0; int trivfs_allow_open = O_READ | O_WRITE; -struct port_class *trivfs_protid_portclasses[1]; -int trivfs_protid_nportclasses = 1; -struct port_class *trivfs_cntl_portclasses[1]; -int trivfs_cntl_nportclasses = 1; + +struct port_class *trivfs_protid_portclasses[2]; +int trivfs_protid_nportclasses = 2; + +struct port_class *trivfs_cntl_portclasses[2]; +int trivfs_cntl_nportclasses = 2; + +/* Which portclass to install on the bootstrap port, default to IPv4. */ +int pfinet_bootstrap_portclass = PORTCLASS_INET; struct port_class *shutdown_notify_class; @@ -224,6 +234,7 @@ enumerate_devices (error_t (*fun) (struc extern void sk_init (void), skb_init (void); extern int net_dev_init (void); +extern void inet6_proto_init (struct net_proto *pro); int main (int argc, @@ -234,8 +245,6 @@ main (int argc, struct stat st; pfinet_bucket = ports_create_bucket (); - trivfs_protid_portclasses[0] = ports_create_class (trivfs_clean_protid, 0); - trivfs_cntl_portclasses[0] = ports_create_class (trivfs_clean_cntl, 0); addrport_class = ports_create_class (clean_addrport, 0); socketport_class = ports_create_class (clean_socketport, 0); trivfs_fsid = getpid (); @@ -258,6 +267,10 @@ main (int argc, #endif inet_proto_init (0); +#ifdef CONFIG_IPV6 + inet6_proto_init (0); +#endif + /* This initializes the Linux network device layer, including initializing each device on the `dev_base' list. For us, that means just loopback_dev, which will get fully initialized now. @@ -276,36 +289,54 @@ main (int argc, (And when not sucessful, it never returns.) */ argp_parse (&pfinet_argp, argc, argv, 0,0,0); - /* Ask init to tell us when the system is going down, - so we can try to be friendly to our correspondents on the network. */ - arrange_shutdown_notification (); - - /* Talk to parent and link us in. */ task_get_bootstrap_port (mach_task_self (), &bootstrap); - if (bootstrap == MACH_PORT_NULL) - error (1, 0, "Must be started as a translator"); - err = trivfs_startup (bootstrap, 0, - trivfs_cntl_portclasses[0], pfinet_bucket, - trivfs_protid_portclasses[0], pfinet_bucket, - &pfinetctl); + pfinet_owner = pfinet_group = 0; - if (err) - error (1, err, "contacting parent"); + if (bootstrap != MACH_PORT_NULL) { + /* Create portclass to install on the bootstrap port. */ + if(trivfs_protid_portclasses[pfinet_bootstrap_portclass] + != MACH_PORT_NULL) + error(1, 0, "No portclass left to assign to bootstrap port"); + + trivfs_protid_portclasses[pfinet_bootstrap_portclass] = + ports_create_class (trivfs_clean_protid, 0); + trivfs_cntl_portclasses[pfinet_bootstrap_portclass] = + ports_create_class (trivfs_clean_cntl, 0); + + /* Talk to parent and link us in. */ + err = trivfs_startup (bootstrap, 0, + trivfs_cntl_portclasses[pfinet_bootstrap_portclass], + pfinet_bucket, trivfs_protid_portclasses + [pfinet_bootstrap_portclass], pfinet_bucket, + &pfinetctl); + + if (err) + error (1, err, "contacting parent"); + + /* Initialize status from underlying node. */ + err = io_stat (pfinetctl->underlying, &st); + if (! err) + { + pfinet_owner = st.st_uid; + pfinet_group = st.st_gid; + } + } + else { /* no bootstrap port. */ + int i; + /* Check that at least one portclass has been bound, + error out otherwise. */ + for (i = 0; i < trivfs_protid_nportclasses; i ++) + if (trivfs_protid_portclasses[i] != MACH_PORT_NULL) + break; + + if (i == trivfs_protid_nportclasses) + error (1, 0, "should be started as a translator.\n"); + } - /* Initialize status from underlying node. */ - err = io_stat (pfinetctl->underlying, &st); - if (err) - { - /* We cannot stat the underlying node. Fallback to the defaults. */ - pfinet_owner = pfinet_group = 0; - err = 0; - } - else - { - pfinet_owner = st.st_uid; - pfinet_group = st.st_gid; - } + /* Ask init to tell us when the system is going down, + so we can try to be friendly to our correspondents on the network. */ + arrange_shutdown_notification (); /* Launch */ ports_manage_port_operations_multithread (pfinet_bucket, @@ -315,6 +346,45 @@ main (int argc, } void +pfinet_bind (int portclass, const char *name) +{ + struct trivfs_control *cntl; + error_t err = 0; + mach_port_t right; + file_t file = file_name_lookup (name, O_CREAT|O_NOTRANS, 0666); + + if (file == MACH_PORT_NULL) + err = errno; + + if (! err) { + trivfs_protid_portclasses[portclass] = + ports_create_class (trivfs_clean_protid, 0); + trivfs_cntl_portclasses[portclass] = + ports_create_class (trivfs_clean_cntl, 0); + + err = trivfs_create_control (file, trivfs_cntl_portclasses[portclass], + pfinet_bucket, + trivfs_protid_portclasses[portclass], + pfinet_bucket, &cntl); + } + + if (! err) + { + right = ports_get_send_right (cntl); + err = file_set_translator (file, 0, FS_TRANS_EXCL | FS_TRANS_SET, + 0, 0, 0, right, MACH_MSG_TYPE_COPY_SEND); + mach_port_deallocate (mach_task_self (), right); + } + + if (err) + error (1, err, name); + + ports_port_deref (cntl); + +} + + +void trivfs_modify_stat (struct trivfs_protid *cred, struct stat *st) { diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/Makefile pfinet6/Makefile --- pfinet-after-import/Makefile 2007-10-07 01:30:31.000000000 +0200 +++ pfinet6/Makefile 2007-10-07 01:21:41.000000000 +0200 @@ -17,7 +17,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. -dir := pfinet +dir := pfinet6 makemode := server core-srcs := datagram.c \ @@ -58,7 +58,25 @@ ipv4-srcs := af_inet.c \ timer.c \ udp.c \ utils.c -LINUXSRCS = $(core-srcs) $(ethernet-srcs) $(ipv4-srcs) \ +ipv6-srcs := addrconf.c \ + af_inet6.c \ + datagram_ipv6.c \ + exthdrs.c \ + icmpv6.c \ + ip6_fib.c \ + ip6_flowlabel.c \ + ip6_input.c \ + ip6_output.c \ + ipv6_sockglue.c \ + mcast.c \ + ndisc.c \ + protocol_ipv6.c \ + raw_ipv6.c \ + reassembly.c \ + route_ipv6.c \ + tcp_ipv6.c \ + udp_ipv6.c +LINUXSRCS = $(core-srcs) $(ethernet-srcs) $(ipv4-srcs) $(ipv6-srcs) \ $(notdir $(wildcard $(addprefix \ $(srcdir)/linux-src/arch/$(asm_syntax)/lib/,\ $(arch-lib-srcs) $(arch-lib-srcs:.c=.S)))) @@ -83,11 +101,11 @@ ASMHEADERS=bitops.h segment.h system.h HURDLIBS=trivfs fshelp threads ports ihash shouldbeinlibc iohelp -target = pfinet +target = pfinet6 include ../Makeconf -vpath %.c $(addprefix $(srcdir)/linux-src/net/,core ethernet ipv4) +vpath %.c $(addprefix $(srcdir)/linux-src/net/,core ethernet ipv4 ipv6) vpath %.c $(srcdir)/linux-src/arch/$(asm_syntax)/lib vpath %.S $(srcdir)/linux-src/arch/$(asm_syntax)/lib @@ -96,7 +114,7 @@ CPPFLAGS += -imacros $(srcdir)/config.h -I$(srcdir)/linux-src/include # Don't ask... We use Linux code. The problem was first noticed when -# compiling `pfinet' with GCC 4.2. +# compiling `pfinet6' with GCC 4.2. CFLAGS += -fno-strict-aliasing asm/checksum.h: ../config.status diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/options.c pfinet6/options.c --- pfinet-after-import/options.c 2007-10-07 01:30:31.000000000 +0200 +++ pfinet6/options.c 2007-10-07 02:51:55.000000000 +0200 @@ -1,6 +1,6 @@ /* Pfinet option parsing - Copyright (C) 1996, 1997, 2000, 2001, 2006 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 2000, 2001, 2006, 2007 Free Software Foundation, Inc. Written by Miles Bader @@ -37,7 +37,11 @@ #include #include #include +#include #include +#include +#include +#include /* Our interface to the set of devices. */ extern error_t find_device (char *name, struct device **device); @@ -50,6 +54,12 @@ extern error_t configure_device (struct extern void inquire_device (struct device *dev, uint32_t *addr, uint32_t *netmask, uint32_t *peer, uint32_t *broadcast); + +/* addrconf.c */ +extern struct inet6_dev *ipv6_find_idev (struct device *dev); +extern int inet6_addr_add (int ifindex, struct in6_addr *pfx, int plen); +extern int inet6_addr_del (int ifindex, struct in6_addr *pfx, int plen); + /* Pfinet options. Used for both startup and runtime. */ static const struct argp_option options[] = @@ -60,6 +70,12 @@ static const struct argp_option options[ {"netmask", 'm', "MASK", 0, "Set the netmask"}, {"peer", 'p', "ADDRESS", 0, "Set the peer address"}, {"gateway", 'g', "ADDRESS", 0, "Set the default gateway"}, + {"ipv4", '4', "NAME", 0, "Put active IPv4 translator on NAME"}, +#ifdef CONFIG_IPV6 + {"ipv6", '6', "NAME", 0, "Put active IPv6 translator on NAME"}, + {"address6", 'A', "ADDR/LEN",0, "Set the global IPv6 address"}, + {"gateway6", 'G', "ADDRESS", 0, "Set the IPv6 default gateway"}, +#endif {"shutdown", 's', 0, 0, "Shut it down"}, {0} }; @@ -74,8 +90,14 @@ struct parse_interface /* The network interface in question. */ struct device *device; - /* New values to apply to it. */ + /* New values to apply to it. (IPv4) */ uint32_t address, netmask, peer, gateway; + +#ifdef CONFIG_IPV6 + /* New IPv6 configuration to apply. */ + struct inet6_ifaddr address6; + struct in6_addr gateway6; +#endif }; /* Used to hold data during argument parsing. */ @@ -108,6 +130,12 @@ parse_hook_add_interface (struct parse_h h->curint->netmask = INADDR_NONE; h->curint->peer = INADDR_NONE; h->curint->gateway = INADDR_NONE; + +#ifdef CONFIG_IPV6 + memset (&h->curint->address6, 0, sizeof (struct inet6_ifaddr)); + memset (&h->curint->gateway6, 0, sizeof (struct in6_addr)); +#endif + return 0; } @@ -146,6 +174,10 @@ parse_opt (int opt, char *arg, struct ar { struct parse_interface *in; uint32_t gateway; +#ifdef CONFIG_IPV6 + struct parse_interface *gw6_in; + char *ptr; +#endif case 'i': /* An interface. */ @@ -196,6 +228,52 @@ parse_opt (int opt, char *arg, struct ar case 'g': h->curint->gateway = ADDR (arg, "gateway"); break; + case '4': + pfinet_bind (PORTCLASS_INET, arg); + + /* Install IPv6 port class on bootstrap port. */ + pfinet_bootstrap_portclass = PORTCLASS_INET6; + break; + +#ifdef CONFIG_IPV6 + case '6': + pfinet_bind (PORTCLASS_INET6, arg); + break; + + case 'A': + if ((ptr = strchr (arg, '/'))) + { + h->curint->address6.prefix_len = atoi (ptr + 1); + if (h->curint->address6.prefix_len > 128) + FAIL (EINVAL, 1, 0, "%s: The prefix-length is invalid", arg); + + *ptr = 0; + } + else + { + h->curint->address6.prefix_len = 64; + fprintf (stderr, "No prefix-length given, defaulting to %s/64.\n", + arg); + } + + if (inet_pton (AF_INET6, arg, &h->curint->address6.addr) <= 0) + PERR (EINVAL, "Malformed address"); + + if (IN6_IS_ADDR_MULTICAST (&h->curint->address6.addr)) + FAIL (EINVAL, 1, 0, "%s: Cannot set interface address to " + "multicast address", arg); + break; + + case 'G': + if (inet_pton (AF_INET6, arg, &h->curint->gateway6) <= 0) + PERR (EINVAL, "Malformed gateway"); + + if (IN6_IS_ADDR_MULTICAST (&h->curint->gateway6)) + FAIL (EINVAL, 1, 0, "%s: Cannot set gateway to " + "multicast address", arg); + break; +#endif /* CONFIG_IPV6 */ + case ARGP_KEY_INIT: /* Initialize our parsing state. */ h = malloc (sizeof (struct parse_hook)); @@ -234,30 +312,73 @@ parse_opt (int opt, char *arg, struct ar #endif gateway = INADDR_NONE; +#ifdef CONFIG_IPV6 + gw6_in = NULL; +#endif for (in = h->interfaces; in < h->interfaces + h->num_interfaces; in++) - if (in->gateway != INADDR_NONE) - { - if (gateway != INADDR_NONE) - FAIL (err, 15, 0, "Cannot have multiple default gateways"); - gateway = in->gateway; - in->gateway = INADDR_NONE; - } - + { + if (in->gateway != INADDR_NONE) + { + if (gateway != INADDR_NONE) + FAIL (err, 15, 0, "Cannot have multiple default gateways"); + gateway = in->gateway; + in->gateway = INADDR_NONE; + } + +#ifdef CONFIG_IPV6 + if (!IN6_IS_ADDR_UNSPECIFIED (&in->gateway6)) + { + if (gw6_in != NULL) + FAIL (err, 15, 0, "Cannot have multiple IPv6 " + "default gateways"); + gw6_in = in; + } +#endif + } /* Successfully finished parsing, return a result. */ __mutex_lock (&global_lock); for (in = h->interfaces; in < h->interfaces + h->num_interfaces; in++) - if (in->address != INADDR_NONE || in->netmask != INADDR_NONE) - { - err = configure_device (in->device, in->address, in->netmask, - in->peer, INADDR_NONE); - if (err) - { - __mutex_unlock (&global_lock); - FAIL (err, 16, 0, "cannot configure interface"); - } - } + { +#ifdef CONFIG_IPV6 + struct inet6_dev *idev = NULL; + if (in->device) + idev = ipv6_find_idev(in->device); +#endif + + if (in->address != INADDR_NONE || in->netmask != INADDR_NONE) + { + err = configure_device (in->device, in->address, in->netmask, + in->peer, INADDR_NONE); + if (err) + { + __mutex_unlock (&global_lock); + FAIL (err, 16, 0, "cannot configure interface"); + } + } + +#ifdef CONFIG_IPV6 + if (!idev) + continue; + + if (!IN6_IS_ADDR_UNSPECIFIED (&in->address6.addr)) + { + /* First let's remove all non-local addresses. */ + struct inet6_ifaddr *ifa = idev->addr_list; + do + if (!IN6_IS_ADDR_LINKLOCAL (&ifa->addr) + && !IN6_IS_ADDR_SITELOCAL (&ifa->addr)) + inet6_addr_del (in->device->ifindex, &ifa->addr, + ifa->prefix_len); + while ((ifa = ifa->if_next)); + + /* Now assign the new address */ + inet6_addr_add (in->device->ifindex, &in->address6.addr, + in->address6.prefix_len); + } +#endif /* CONFIG_IPV6 */ + } /* Set the default gateway. This code is cobbled together from what the SIOCADDRT ioctl code does, and from the apparent functionality @@ -315,6 +436,13 @@ parse_opt (int opt, char *arg, struct ar } } + /* Set IPv6 default router. */ +#ifdef CONFIG_IPV6 + rt6_purge_dflt_routers (0); + if (gw6_in) + rt6_add_dflt_router (&gw6_in->gateway6, gw6_in->device); +#endif + __mutex_unlock (&global_lock); /* Fall through to free hook. */ @@ -372,6 +500,40 @@ trivfs_append_args (struct trivfs_contro ADD_ADDR_OPT ("gateway", FIB_RES_GW (res)); #undef ADD_ADDR_OPT + +#ifdef CONFIG_IPV6 + struct inet6_dev *idev = ipv6_find_idev(dev); + if (idev) + { + struct inet6_ifaddr *ifa = idev->addr_list; + struct in6_addr daddr; + static char addr_buf[INET6_ADDRSTRLEN]; + + /* Look for IPv6 default route (we use the first ifa->addr as + source address), but don't yet push it to the option stack. */ + memset (&daddr, 0, sizeof(daddr)); + struct fib6_node *fib = fib6_lookup + (&ip6_routing_table, &daddr, &ifa->addr); + struct rt6_info *rt6i = fib->leaf; + + /* Push all IPv6 addresses assigned to the interface. */ + do + { + inet_ntop (AF_INET6, &ifa->addr, addr_buf, INET6_ADDRSTRLEN); + ADD_OPT ("--address6=%s/%d", addr_buf, ifa->prefix_len); + } + while ((ifa = ifa->if_next)); + + /* Last not least push --gateway6 option. */ + if(rt6i->rt6i_dev == dev) + { + inet_ntop (AF_INET6, &rt6i->rt6i_gateway, addr_buf, + INET6_ADDRSTRLEN); + ADD_OPT ("--gateway6=%s", addr_buf); + } + } +#endif /* CONFIG_IPV6 */ + #undef ADD_OPT return err; diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/pfinet.h pfinet6/pfinet.h --- pfinet-after-import/pfinet.h 2007-10-07 01:30:31.000000000 +0200 +++ pfinet6/pfinet.h 2007-10-07 01:21:41.000000000 +0200 @@ -92,4 +92,22 @@ void clean_socketport (void *); typedef struct sock_user *sock_user_t; typedef struct sock_addr *sock_addr_t; +/* pfinet6 port classes. */ +enum { + PORTCLASS_INET, + PORTCLASS_INET6, +}; + +extern struct port_class *trivfs_protid_portclasses[]; +extern int trivfs_protid_nportclasses; + +extern struct port_class *trivfs_cntl_portclasses[2]; +extern int trivfs_cntl_nportclasses; + +/* Which portclass to install on the bootstrap port. */ +extern int pfinet_bootstrap_portclass; + +/* Install portclass on node NAME. */ +void pfinet_bind (int portclass, const char *name); + #endif diff -pNru -x .git -x ChangeLog -x '*~' pfinet-after-import/socket-ops.c pfinet6/socket-ops.c --- pfinet-after-import/socket-ops.c 2007-10-07 01:30:31.000000000 +0200 +++ pfinet6/socket-ops.c 2007-10-07 01:21:41.000000000 +0200 @@ -1,5 +1,5 @@ /* Interface functions for the socket.defs interface. - Copyright (C) 1995,96,97,99,2000,02 Free Software Foundation, Inc. + Copyright (C) 1995,96,97,99,2000,02,07 Free Software Foundation, Inc. Written by Michael I. Bushnell, p/BSG. This file is part of the GNU Hurd. @@ -80,7 +80,11 @@ S_socket_create (struct trivfs_protid *m isroot = 1; } - err = - (*net_families[PF_INET]->create) (sock, protocol); + if (master->pi.class == trivfs_protid_portclasses[PORTCLASS_INET]) + err = - (*net_families[PF_INET]->create) (sock, protocol); + else + err = - (*net_families[PF_INET6]->create) (sock, protocol); + if (err) sock_release (sock); else @@ -295,7 +299,7 @@ S_socket_create_address (mach_port_t ser struct sock_addr *addrstruct; const struct sockaddr *const sa = (void *) data; - if (sockaddr_type != AF_INET) + if (sockaddr_type != AF_INET && sockaddr_type != AF_INET6) return EAFNOSUPPORT; if (sa->sa_family != sockaddr_type || data_len < offsetof (struct sockaddr, sa_data))