Remove kprof's timer (XCC)
[akaros.git] / kern / include / ip.h
index 85f09a6..dd1edcc 100644 (file)
@@ -1,13 +1,40 @@
-// 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 */
 
@@ -39,6 +66,12 @@ enum {
        Connected = 4,
 };
 
+enum {
+       SHUT_RD = 0,
+       SHUT_WR = 1,
+       SHUT_RDWR = 2,
+};
+
 /*
  *  one per conversation directory
  */
@@ -79,6 +112,10 @@ struct conv {
        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];
 
@@ -145,9 +182,9 @@ struct Iplifc {
        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;
 };
@@ -158,7 +195,7 @@ struct Iplink {
        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;
 };
@@ -186,6 +223,7 @@ struct Ipifc {
        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 */
@@ -206,7 +244,7 @@ struct Ipifc {
 
        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 */
 };
 
@@ -256,14 +294,15 @@ struct Proto {
        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);
@@ -355,12 +394,12 @@ int Fsbuiltinproto(struct Fs *, uint8_t unused_uint8_t);
 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 {
@@ -493,11 +532,11 @@ struct arpent {
        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 */
@@ -505,7 +544,7 @@ struct arpent {
 
 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);
@@ -530,8 +569,29 @@ extern void v4tov6(uint8_t * v6, uint8_t * v4);
 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];
@@ -578,11 +638,7 @@ extern void ipifcremroute(struct Fs *, int unused_int, uint8_t * u8pt,
                                                  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);
 
 /*
@@ -609,11 +665,23 @@ extern void ip_init(struct Fs *);
 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
@@ -831,7 +899,6 @@ extern int ReTransTimer;
 int kdial(char *dest, char *local, char *dir, int *cfdp);
 
 /* network interfaces and ethernet */
-// INFERNO
 
 enum {
        Nmaxaddr = 64,
@@ -889,8 +956,26 @@ struct netaddr {
 };
 
 /*
+ * 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;
 
@@ -904,6 +989,7 @@ struct netif {
        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 */
@@ -931,17 +1017,18 @@ struct netif {
        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
@@ -949,7 +1036,7 @@ int activemulti(struct netif *, uint8_t *, int);
 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 */
 };
 
@@ -959,7 +1046,6 @@ struct etherpkt {
        uint8_t type[2];
        uint8_t data[1500];
 };
-// INFERNO
 enum {
        MaxEther = 32,
        MaxFID = 16,
@@ -997,8 +1083,7 @@ struct ether {
        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);
@@ -1007,5 +1092,3 @@ extern int archether(int unused_int, struct ether *);
 
 #define NEXT_RING(x, len) (((x) + 1) % (len))
 #define PREV_RING(x, len) (((x) == 0) ? (len) - 1: (x) - 1)
-
-#endif /* ROS_KERN_IP_H */