#ifdef RSS_DEBUG
ether_pktinfo_try++;
#endif
- ether_dispatch(pi->pi_netisr, m, chain);
-
+ netisr_hashcheck(pi->pi_netisr, m, pi);
+ if (m->m_flags & M_HASH) {
+ ether_dispatch(pi->pi_netisr, m, chain);
#ifdef RSS_DEBUG
- ether_pktinfo_hit++;
+ ether_pktinfo_hit++;
#endif
- logether(chain_end, ifp);
- return;
+ logether(chain_end, ifp);
+ return;
+ }
}
#ifdef RSS_DEBUG
else if (ifp->if_capenable & IFCAP_RSS) {
static void netmsg_sync_func(netmsg_t msg);
static void netmsg_service_loop(void *arg);
static void cpu0_cpufn(struct mbuf **mp, int hoff);
+static void netisr_nohashck(struct mbuf *, const struct pktinfo *);
struct netmsg_port_registration {
TAILQ_ENTRY(netmsg_port_registration) npr_entry;
ni = &netisrs[num];
ni->ni_handler = handler;
+ ni->ni_hashck = netisr_nohashck;
ni->ni_cpufn = cpufn;
netmsg_init(&ni->ni_netmsg, NULL, &netisr_adone_rport, 0, NULL);
}
void
+netisr_register_hashcheck(int num, netisr_hashck_t hashck)
+{
+ struct netisr *ni;
+
+ KASSERT((num > 0 && num <= NELEM(netisrs)),
+ ("netisr_register: bad isr %d", num));
+
+ ni = &netisrs[num];
+ ni->ni_hashck = hashck;
+}
+
+void
netisr_register_rollup(netisr_ru_t ru_func)
{
struct netmsg_rollup *ru;
#endif
br->br_isset = 0;
}
+
+static void
+netisr_nohashck(struct mbuf *m, const struct pktinfo *pi __unused)
+{
+ m->m_flags &= ~M_HASH;
+}
+
+void
+netisr_hashcheck(int num, struct mbuf *m, const struct pktinfo *pi)
+{
+ struct netisr *ni;
+
+ if (num < 0 || num >= NETISR_MAX)
+ panic("Bad isr %d", num);
+
+ /*
+ * Valid netisr?
+ */
+ ni = &netisrs[num];
+ if (ni->ni_handler == NULL)
+ panic("Unregistered isr %d\n", num);
+
+ ni->ni_hashck(m, pi);
+}
*/
struct netisr {
netisr_fn_t ni_handler; /* packet handler function */
- netisr_ru_t ni_rufunc; /* rollup function */
+ netisr_hashck_t ni_hashck; /* hash check function */
netisr_cpufn_t ni_cpufn; /* characterize pkt return cpu */
struct netmsg_base ni_netmsg; /* for sched_netisr() (no-data) */
};
lwkt_port_t cur_netport(void);
void netisr_register(int, netisr_fn_t, netisr_cpufn_t);
+void netisr_register_hashcheck(int, netisr_hashck_t);
void netisr_register_rollup(netisr_ru_t ru_func);
void netisr_characterize(int num, struct mbuf **mp, int hoff);
+void netisr_hashcheck(int num, struct mbuf *m,
+ const struct pktinfo *pi);
int netisr_queue(int, struct mbuf *);
struct netisr_barrier *netisr_barrier_create(void);
#include <sys/protosw.h>
#endif
+struct pktinfo;
+
typedef void (*netisr_fn_t)(netmsg_t);
typedef void (*netisr_ru_t)(void);
typedef void (*netisr_cpufn_t)(struct mbuf **, int);
+typedef void (*netisr_hashck_t)(struct mbuf *, const struct pktinfo *);
#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
ip_cpufn(mptr, hoff, IP_MPORT_IN);
}
-#if 0
-
/*
- * Map a packet to a protocol processing thread and return the thread's port.
+ * Verify and adjust the hash value of the packet.
+ *
* Unlike ip_cpufn(), the packet content is not accessed. The packet info
- * (pi) and the hash of the packet (m_pkthdr.hash) is used instead. NULL is
- * returned if the packet info does not contain enough information.
+ * (pi) and the hash of the packet (m_pkthdr.hash) is used instead.
*
* Caller has already made sure that m_pkthdr.hash is valid, i.e. m_flags
* has M_HASH set.
*/
-lwkt_port_t
-ip_mport_pktinfo(const struct pktinfo *pi, struct mbuf *m)
+void
+ip_hashcheck(struct mbuf *m, const struct pktinfo *pi)
{
- lwkt_port_t port;
-
+ KASSERT((m->m_flags & M_HASH), ("no valid packet hash\n"));
KASSERT(m->m_pkthdr.hash < ncpus2,
("invalid packet hash %#x\n", m->m_pkthdr.hash));
*/
if (pi->pi_flags & PKTINFO_FLAG_FRAG) {
m->m_pkthdr.hash = 0;
- return cpu_portfn(0);
+ return;
}
switch (pi->pi_l3proto) {
case IPPROTO_TCP:
- port = cpu_portfn(m->m_pkthdr.hash);
- break;
-
case IPPROTO_UDP:
- port = cpu_portfn(m->m_pkthdr.hash);
break;
default:
- port = NULL;
+ /* Let software calculate the hash */
+ m->m_flags &= ~M_HASH;
break;
}
- return port;
}
-#endif
-
/*
* This is used to map a socket to a message port for sendmsg() and friends.
* It is not called for any other purpose. In the case of TCP we just return
#endif
netisr_register(NETISR_IP, ip_input_handler, ip_cpufn_in);
+ netisr_register_hashcheck(NETISR_IP, ip_hashcheck);
}
/* Do transport protocol processing. */
void ip_cpufn(struct mbuf **, int, int);
void ip_cpufn_in(struct mbuf **, int);
+void ip_hashcheck(struct mbuf *, const struct pktinfo *);
boolean_t
ip_lengthcheck(struct mbuf **, int);