Esempio n. 1
0
int rtnl_u32_add_key_uint8(struct rtnl_cls *cls, uint8_t val, uint8_t mask,
			   int off, int offmask)
{
	int shift = 24 - 8 * (off & 3);

	return rtnl_u32_add_key(cls, htonl((uint32_t)val << shift),
				htonl((uint32_t)mask << shift),
				off & ~3, offmask);
}
Esempio n. 2
0
/**
 * Append new selector key to match a 16-bit number
 *
 * @arg cls	classifier to be modified
 * @arg val	value to be matched (host byte-order)
 * @arg mask	mask to be applied before matching (host byte-order)
 * @arg off	offset, in bytes, to start matching
 * @arg offmask	offset mask
*/
int rtnl_u32_add_key_uint16(struct rtnl_cls *cls, uint16_t val, uint16_t mask,
			    int off, int offmask)
{
	int shift = ((off & 3) == 0 ? 16 : 0);
	if (off % 2)
		return -NLE_INVAL;

	return rtnl_u32_add_key(cls, htonl((uint32_t)val << shift),
				htonl((uint32_t)mask << shift),
				off & ~3, offmask);
}
Esempio n. 3
0
int rtnl_u32_add_key_in6_addr(struct rtnl_cls *cls, const struct in6_addr *addr,
			      uint8_t bitmask, int off, int offmask)
{
	int i, err;

	for (i = 1; i <= 4; i++) {
		if (32 * i - bitmask <= 0) {
			if ((err = rtnl_u32_add_key(cls, addr->s6_addr32[i-1],
						0xFFFFFFFF, off+4*(i-1), offmask)) < 0)
				return err;
		}
		else if (32 * i - bitmask < 32) {
			uint32_t mask = 0xFFFFFFFF << (32 * i - bitmask);
			if ((err = rtnl_u32_add_key(cls, addr->s6_addr32[i-1],
						htonl(mask), off+4*(i-1), offmask)) < 0)
				return err;
		}
		/* otherwise, if (32*i - bitmask >= 32) no key is generated */
	}

	return 0;
}
Esempio n. 4
0
int rtnl_u32_add_key_in_addr(struct rtnl_cls *cls, const struct in_addr *addr,
			     uint8_t bitmask, int off, int offmask)
{
	uint32_t mask = 0xFFFFFFFF << (32 - bitmask);
	return rtnl_u32_add_key(cls, addr->s_addr, htonl(mask), off, offmask);
}
Esempio n. 5
0
/**
 * Append new selector key to match a 32-bit number
 *
 * @arg cls	classifier to be modified
 * @arg val	value to be matched (host byte-order)
 * @arg mask	mask to be applied before matching (host byte-order)
 * @arg off	offset, in bytes, to start matching
 * @arg offmask	offset mask
*/
int rtnl_u32_add_key_uint32(struct rtnl_cls *cls, uint32_t val, uint32_t mask,
			    int off, int offmask)
{
	return rtnl_u32_add_key(cls, htonl(val), htonl(mask),
				off & ~3, offmask);
}
Esempio n. 6
0
Try<Nothing> encode<icmp::Classifier>(
    const Netlink<struct rtnl_cls>& cls,
    const icmp::Classifier& classifier)
{
  // ICMP packets are one type of IP packets.
  rtnl_cls_set_protocol(cls.get(), ETH_P_IP);

  int error = rtnl_tc_set_kind(TC_CAST(cls.get()), "u32");
  if (error != 0) {
    return Error(
        "Failed to set the kind of the classifier: " +
        string(nl_geterror(error)));
  }

  // To avoid confusion, we only use u32 selectors which are used to
  // match arbitrary 32-bit content in a packet.

  // Format of an IP packet at offset 8. The IP protocol field is at
  // offset 9. ICMP has protocol = 1.
  //        +--------+--------+--------+--------+
  //        |   X    | Proto. |   X    |   X    |
  //        +--------+--------+--------+--------+
  // Offset:    8        9        10       11
  uint32_t protocol = 0x00010000;
  uint32_t mask = 0x00ff0000; // Ignore offset 8, 10, 11.

  // To match ICMP packets (protocol = 1).
  error = rtnl_u32_add_key(
      cls.get(),
      htonl(protocol),
      htonl(mask),
      8, // Offset from which to start matching.
      0);

  if (error != 0) {
    return Error(
        "Failed to add selector for IP protocol: " +
        string(nl_geterror(error)));
  }

  if (classifier.destinationIP.isSome()) {
    Try<struct in_addr> in = classifier.destinationIP.get().in();
    if (in.isError()) {
      return Error("Destination IP is not an IPv4 address");
    }

    // To match those IP packets that have the given destination IP.
    error = rtnl_u32_add_key(
        cls.get(),
        in.get().s_addr,
        htonl(0xffffffff),
        16, // Offset from which to start matching.
        0);

    if (error != 0) {
      return Error(
          "Failed to add selector for destination IP address: " +
           string(nl_geterror(error)));
    }
  }

  return Nothing();
}