-// INFERNO
-
-#ifndef ROS_KERN_IP_H
-#define ROS_KERN_IP_H
+/* Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
+ * Portions Copyright © 1997-1999 Vita Nuova Limited
+ * Portions Copyright © 2000-2007 Vita Nuova Holdings Limited
+ * (www.vitanuova.com)
+ * Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+ *
+ * Modified for the Akaros operating system:
+ * Copyright (c) 2013-2014 The Regents of the University of California
+ * Copyright (c) 2013-2015 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+
+#pragma once
+#include <ns.h>
enum {
Addrlen = 64,
Maxproto = 20,
Nhash = 64,
- Maxincall = 5,
+ Maxincall = 500,
Nchans = 256,
MAClen = 16, /* longest mac address */
Connected = 4,
};
+enum {
+ SHUT_RD = 0,
+ SHUT_WR = 1,
+ SHUT_RDWR = 2,
+};
+
/*
* one per conversation directory
*/
struct queue *sq; /* snooping queue */
atomic_t snoopers; /* number of processes with snoop open */
+ struct fdtap_slist data_taps;
+ struct fdtap_slist listen_taps;
+ spinlock_t tap_lock;
+
struct rendez cr;
char cerr[ERRMAX];
uint8_t tentative; /* =1 => v6 dup disc on, =0 => confirmed unique */
uint8_t onlink; /* =1 => onlink, =0 offlink. */
uint8_t autoflag; /* v6 autonomous flag */
- long validlt; /* v6 valid lifetime */
- long preflt; /* v6 preferred lifetime */
- long origint; /* time when addr was added */
+ uint64_t validlt; /* v6 valid lifetime */
+ uint64_t preflt; /* v6 preferred lifetime */
+ uint64_t origint; /* time when addr was added */
struct Iplink *link; /* addresses linked to this lifc */
struct Iplifc *next;
};
struct Iplifc *lifc;
struct Iplink *selflink; /* next link for this local address */
struct Iplink *lifclink; /* next link for this ifc */
- uint32_t expire;
+ uint64_t expire;
struct Iplink *next; /* free list */
struct kref ref;
};
struct medium *m; /* Media pointer */
int maxtu; /* Maximum transfer unit */
int mintu; /* Minumum tranfer unit */
+ unsigned int feat; /* Offload features */
int mbps; /* megabits per second */
void *arg; /* medium specific */
int reassemble; /* reassemble IP packets before forwarding */
uint8_t sendra6; /* == 1 => send router advs on this ifc */
uint8_t recvra6; /* == 1 => recv router advs on this ifc */
- struct routerparams rp; /* router parameters as in RFC 2461, pp.40--43.
+ struct routerparams rp; /* router parameters as in RFC 2461, pp.40--43.
used only if node is router */
};
int x; /* protocol index */
int ipproto; /* ip protocol type */
- char *(*connect) (struct conv *, char **unused_char_pp_t, int);
- char *(*announce) (struct conv *, char **unused_char_pp_t, int);
- char *(*bind) (struct conv *, char **unused_char_pp_t, int);
+ void (*connect)(struct conv *, char **, int);
+ void (*announce)(struct conv *, char **, int);
+ void (*bind)(struct conv *, char **, int);
int (*state) (struct conv *, char *unused_char_p_t, int);
void (*create) (struct conv *);
void (*close) (struct conv *);
+ void (*shutdown)(struct conv *, int);
void (*rcv) (struct Proto *, struct Ipifc *, struct block *);
- char *(*ctl) (struct conv *, char **unused_char_pp_t, int);
+ void (*ctl)(struct conv *, char **, int);
void (*advise) (struct Proto *, struct block *, char *unused_char_p_t);
int (*stats) (struct Proto *, char *unused_char_p_t, int);
int (*local) (struct conv *, char *unused_char_p_t, int);
struct conv *Fsprotoclone(struct Proto *, char *unused_char_p_t);
struct Proto *Fsrcvpcol(struct Fs *, uint8_t unused_uint8_t);
struct Proto *Fsrcvpcolx(struct Fs *, uint8_t unused_uint8_t);
-char *Fsstdconnect(struct conv *, char **unused_char_pp_t, int);
-char *Fsstdannounce(struct conv *, char **unused_char_pp_t, int);
-char *Fsstdbind(struct conv *, char **unused_char_pp_t, int);
+void Fsstdconnect(struct conv *, char **, int);
+void Fsstdannounce(struct conv *, char **, int);
+void Fsstdbind(struct conv *, char **, int);
uint32_t scalednconv(void);
-/*
+/*
* logging
*/
enum {
struct arpent *hash;
struct block *hold;
struct block *last;
- unsigned int ctime; /* time entry was created or refreshed */
- unsigned int utime; /* time entry was last used */
+ uint64_t ctime; /* time entry was created or refreshed */
+ uint64_t utime; /* time entry was last used */
uint8_t state;
struct arpent *nextrxt; /* re-transmit chain */
- unsigned int rtime; /* time for next retransmission */
+ uint64_t rtime; /* time for next retransmission */
uint8_t rxtsrem;
struct Ipifc *ifc;
uint8_t ifcid; /* must match ifc->id */
extern void arpinit(struct Fs *);
extern int arpread(struct arp *, char *unused_char_p_t, uint32_t, int);
-extern int arpwrite(struct Fs *, char *unused_char_p_t, int);
+extern int arpwrite(struct Fs *, char *unused_char_p_t, long);
extern struct arpent *arpget(struct arp *, struct block *bp, int version,
struct Ipifc *ifc, uint8_t * ip, uint8_t * h);
extern void arprelease(struct arp *, struct arpent *a);
extern int v6tov4(uint8_t * v4, uint8_t * v6);
//extern int eipfmt(Fmt*);
-#define ipmove(x, y) memmove(x, y, IPaddrlen)
-#define ipcmp(x, y) ( (x)[IPaddrlen-1] != (y)[IPaddrlen-1] || memcmp(x, y, IPaddrlen) )
+
+#ifdef CONFIG_RISCV
+#warning "Potentially unaligned IP addrs!"
+#endif
+static inline void ipmove(unsigned char *x, unsigned char *y)
+{
+ uint32_t *a = (uint32_t *)x;
+ uint32_t *b = (uint32_t *)y;
+
+ a[0] = b[0];
+ a[1] = b[1];
+ a[2] = b[2];
+ a[3] = b[3];
+}
+
+static inline long ipcmp(unsigned char *x, unsigned char *y)
+{
+ uint32_t *a = (uint32_t *)x;
+ uint32_t *b = (uint32_t *)y;
+ return (a[0] ^ b[0]) | (a[1] ^ b[1]) |
+ (a[2] ^ b[2]) | (a[3] ^ b[3]);
+}
+
extern uint8_t IPv4bcast[IPaddrlen];
extern uint8_t IPv4bcastobs[IPaddrlen];
uint8_t * u8pt2);
extern void ipifcremmulti(struct conv *c, uint8_t * ma, uint8_t * ia);
extern void ipifcaddmulti(struct conv *c, uint8_t * ma, uint8_t * ia);
-extern char *ipifcrem(struct Ipifc *ifc, char **argv, int argc);
-extern char *ipifcadd(struct Ipifc *ifc, char **argv, int argc, int tentative,
- struct Iplifc *lifcp);
extern long ipselftabread(struct Fs *, char *a, uint32_t offset, int n);
-extern char *ipifcaddpref6(struct Ipifc *ifc, char **argv, int argc);
extern void ipsendra6(struct Fs *f, int on);
/*
extern void update_mtucache(uint8_t * unused_uint8_p_t, uint32_t);
extern uint32_t restrict_mtu(uint8_t * unused_uint8_p_t, uint32_t);
-/*
- * bootp.c
- */
-char *(*bootp) (struct Ipifc * unused_ipifc);
-int (*bootpread) (char *unused_char_p_t, uint32_t, int);
+static inline void ptclcsum_finalize(struct block *bp, unsigned int feat)
+{
+ unsigned int flag = bp->flag & BCKSUM_FLAGS;
+ uint8_t *csum_store;
+
+ if (flag && (flag & feat) != flag) {
+ csum_store = bp->rp + bp->checksum_start + bp->checksum_offset;
+ /* NOTE pseudo-header partial checksum (if any) is already placed at
+ * csum_store (e.g. tcpcksum), and the ptclcsum() below will include
+ * that partial checksum as part of the calculation.
+ */
+ hnputs((uint16_t *)csum_store,
+ ptclcsum(bp, bp->checksum_start,
+ BLEN(bp) - bp->checksum_start));
+ bp->flag &= ~BCKSUM_FLAGS;
+ }
+}
/*
* iprouter.c
int kdial(char *dest, char *local, char *dir, int *cfdp);
/* network interfaces and ethernet */
-// INFERNO
enum {
Nmaxaddr = 64,
};
/*
+ * These flags overlap with block flags, to make detecting unsupported
+ * offloads efficient.
+ */
+#define NETF_BASE_SHIFT (NS_SHIFT_MAX + 1)
+#define NETF_PADMIN_SHIFT (NETF_BASE_SHIFT + 0)
+#define NETF_SG_SHIFT (NETF_BASE_SHIFT + 1)
+#define NETF_LRO_SHIFT (NETF_BASE_SHIFT + 2)
+enum {
+ NETF_IPCK = (1 << NS_IPCK_SHIFT), /* xmit ip checksum */
+ NETF_UDPCK = (1 << NS_UDPCK_SHIFT), /* xmit udp checksum */
+ NETF_TCPCK = (1 << NS_TCPCK_SHIFT), /* xmit tcp checksum */
+ NETF_PADMIN = (1 << NETF_PADMIN_SHIFT), /* device pads to mintu */
+ NETF_SG = (1 << NETF_SG_SHIFT), /* device can do scatter/gather */
+ NETF_TSO = (1 << NS_TSO_SHIFT), /* device can do TSO */
+ NETF_LRO = (1 << NETF_LRO_SHIFT), /* device can do LRO */
+};
+/*
* a network interface
*/
+struct ether;
struct netif {
qlock_t qlock;
int alen; /* address length */
int mbps; /* megabits per sec */
int link; /* link status */
+ unsigned int feat; /* dev features */
uint8_t addr[Nmaxaddr];
uint8_t bcast[Nmaxaddr];
struct netaddr *maddr; /* known multicast addresses */
void (*scanbs) (void *, unsigned nt); /* scan for base stations */
};
-void netifinit(struct netif *, char *, int, uint32_t);
-struct walkqid *netifwalk(struct netif *, struct chan *, struct chan *, char **,
+void netifinit(struct ether *, char *, int, uint32_t);
+struct walkqid *netifwalk(struct ether *, struct chan *, struct chan *,
+ char **,
int);
-struct chan *netifopen(struct netif *, struct chan *, int);
-void netifclose(struct netif *, struct chan *);
-long netifread(struct netif *, struct chan *, void *, long, uint32_t);
-struct block *netifbread(struct netif *, struct chan *, long, uint32_t);
-long netifwrite(struct netif *, struct chan *, void *, long);
-int netifwstat(struct netif *, struct chan *, uint8_t *, int);
-int netifstat(struct netif *, struct chan *, uint8_t *, int);
-int activemulti(struct netif *, uint8_t *, int);
+struct chan *netifopen(struct ether *, struct chan *, int);
+void netifclose(struct ether *, struct chan *);
+long netifread(struct ether *, struct chan *, void *, long, uint32_t);
+struct block *netifbread(struct ether *, struct chan *, long, uint32_t);
+long netifwrite(struct ether *, struct chan *, void *, long);
+int netifwstat(struct ether *, struct chan *, uint8_t *, int);
+int netifstat(struct ether *, struct chan *, uint8_t *, int);
+int activemulti(struct ether *, uint8_t *, int);
/*
* Ethernet specific
enum {
Eaddrlen = 6,
ETHERMINTU = 60, /* minimum transmit size */
- ETHERMAXTU = 1514, /* maximum transmit size */
+ ETHERMAXTU = 1500, /* maximum transmit size */
ETHERHDRSIZE = 14, /* size of an ethernet header */
};
uint8_t type[2];
uint8_t data[1500];
};
-// INFERNO
enum {
- MaxEther = 4,
+ MaxEther = 32,
MaxFID = 16,
Ntypes = 8,
};
int ctlrno;
char *type;
int irq;
+ unsigned int tbdf;
int port;
int minmtu;
int maxmtu;
void (*closed) (struct ether *);
void (*detach) (struct ether *);
void (*transmit) (struct ether *);
- void (*interrupt) (struct hw_trapframe *, void *);
long (*ifstat) (struct ether *, void *, long, uint32_t);
long (*ctl) (struct ether *, void *, long); /* custom ctl messages */
void (*power) (struct ether *, int); /* power on/off */
int nvlan;
struct ether *vlans[MaxFID];
- /* another case where we wish we had anon struct members. */
- struct netif netif;
+ struct netif;
};
extern struct block *etheriq(struct ether *, struct block *, int);
#define NEXT_RING(x, len) (((x) + 1) % (len))
#define PREV_RING(x, len) (((x) == 0) ? (len) - 1: (x) - 1)
-
-#endif /* ROS_KERN_IP_H */