Example #1
0
/*
 * Set up an L2T entry and send any packets waiting in the arp queue.  The
 * supplied skb is used for the CPL_L2T_WRITE_REQ.  Must be called with the
 * entry locked.
 */
static int setup_l2e_send_pending(struct t3cdev *dev, struct sk_buff *skb,
				  struct l2t_entry *e)
{
	struct cpl_l2t_write_req *req;

	if (!skb) {
		skb = alloc_skb(sizeof(*req), GFP_ATOMIC);
		if (!skb)
			return -ENOMEM;
	}

	req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req));
	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, e->idx));
	req->params = htonl(V_L2T_W_IDX(e->idx) | V_L2T_W_IFF(e->smt_idx) |
			    V_L2T_W_VLAN(e->vlan & VLAN_VID_MASK) |
			    V_L2T_W_PRIO(vlan_prio(e)));
	memcpy(e->dmac, e->neigh->ha, sizeof(e->dmac));
	memcpy(req->dst_mac, e->dmac, sizeof(req->dst_mac));
	skb->priority = CPL_PRIORITY_CONTROL;
	cxgb3_ofld_send(dev, skb);
	while (e->arpq_head) {
		skb = e->arpq_head;
		e->arpq_head = skb->next;
		skb->next = NULL;
		cxgb3_ofld_send(dev, skb);
	}
	e->arpq_tail = NULL;
	e->state = L2T_STATE_VALID;

	return 0;
}
Example #2
0
int
sysctl_l2t(SYSCTL_HANDLER_ARGS)
{
	struct adapter *sc = arg1;
	struct l2t_data *l2t = sc->l2t;
	struct l2t_entry *e;
	struct sbuf *sb;
	int rc, i, header = 0;
	char ip[INET6_ADDRSTRLEN];

	if (l2t == NULL)
		return (ENXIO);

	rc = sysctl_wire_old_buffer(req, 0);
	if (rc != 0)
		return (rc);

	sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req);
	if (sb == NULL)
		return (ENOMEM);

	e = &l2t->l2tab[0];
	for (i = 0; i < l2t->l2t_size; i++, e++) {
		mtx_lock(&e->lock);
		if (e->state == L2T_STATE_UNUSED)
			goto skip;

		if (header == 0) {
			sbuf_printf(sb, " Idx IP address      "
			    "Ethernet address  VLAN/P LP State Users Port");
			header = 1;
		}
		if (e->state == L2T_STATE_SWITCHING)
			ip[0] = 0;
		else {
			inet_ntop(e->ipv6 ? AF_INET6 : AF_INET, &e->addr[0],
			    &ip[0], sizeof(ip));
		}

		/*
		 * XXX: e->ifp may not be around.
		 * XXX: IPv6 addresses may not align properly in the output.
		 */
		sbuf_printf(sb, "\n%4u %-15s %02x:%02x:%02x:%02x:%02x:%02x %4d"
			   " %u %2u   %c   %5u %s",
			   e->idx, ip, e->dmac[0], e->dmac[1], e->dmac[2],
			   e->dmac[3], e->dmac[4], e->dmac[5],
			   e->vlan & 0xfff, vlan_prio(e), e->lport,
			   l2e_state(e), atomic_load_acq_int(&e->refcnt),
			   e->ifp->if_xname);
skip:
		mtx_unlock(&e->lock);
	}

	rc = sbuf_finish(sb);
	sbuf_delete(sb);

	return (rc);
}