예제 #1
0
파일: netlink.cpp 프로젝트: direvius/porto
TError TNlCgFilter::Remove(const TNlLink &link) {
    TError error = TError::Success();
    struct rtnl_cls *cls;
    int ret;

    cls = rtnl_cls_alloc();
    if (!cls)
        return TError(EError::Unknown, std::string("Unable to allocate filter object"));

    rtnl_tc_set_ifindex(TC_CAST(cls), link.GetIndex());

    ret = rtnl_tc_set_kind(TC_CAST(cls), FilterType);
    if (ret < 0) {
        error = TError(EError::Unknown, std::string("Unable to set filter type: ") + nl_geterror(ret));
        goto free_cls;
    }

    rtnl_cls_set_prio(cls, FilterPrio);
    rtnl_cls_set_protocol(cls, 0);
    rtnl_tc_set_parent(TC_CAST(cls), Parent);

    link.Dump("remove", cls);

    ret = rtnl_cls_delete(link.GetSock(), cls, 0);
    if (ret < 0)
        error = TError(EError::Unknown, std::string("Unable to remove filter: ") + nl_geterror(ret));

free_cls:
    rtnl_cls_put(cls);

    return error;
}
예제 #2
0
void nl_cli_cls_parse_proto(struct rtnl_cls *cls, char *arg)
{
	int proto;

	if ((proto = nl_str2ether_proto(arg)) < 0)
		nl_cli_fatal(proto, "Unknown protocol \"%s\".", arg);

	rtnl_cls_set_protocol(cls, proto);
}
예제 #3
0
파일: basic.cpp 프로젝트: LlsDimple/mesos
Try<Nothing> encode<basic::Classifier>(
    const Netlink<struct rtnl_cls>& cls,
    const basic::Classifier& classifier)
{
  rtnl_cls_set_protocol(cls.get(), classifier.protocol());

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

  return Nothing();
}
/* 
 * Function that adds a new filter and attach it to a hash table 
 * and set next hash table link with hash mask
 *
 */
static
int u32_add_filter_on_ht_with_hashmask(struct nl_sock *sock, struct rtnl_link *rtnlLink, uint32_t prio, 
	    uint32_t keyval, uint32_t keymask, int keyoff, int keyoffmask,
	    uint32_t htid, uint32_t htlink, uint32_t hmask, uint32_t hoffset, struct rtnl_act *act, struct rtnl_act *act2)
{
    struct rtnl_cls *cls;
    int err;

    cls=rtnl_cls_alloc();
    if (!(cls)) {
        printf("Can not allocate classifier\n");
        nl_socket_free(sock);
        exit(1);
    }
    
    rtnl_tc_set_link(TC_CAST(cls), rtnlLink);

    if ((err = rtnl_tc_set_kind(TC_CAST(cls), "u32"))) {
        printf("Can not set classifier as u32\n");
        return 1;
    }

    rtnl_cls_set_prio(cls, prio);
    rtnl_cls_set_protocol(cls, ETH_P_IP);

    rtnl_tc_set_parent(TC_CAST(cls), TC_HANDLE(0xffff, 0));
    
    if (htid)
	rtnl_u32_set_hashtable(cls, htid);

    rtnl_u32_add_key_uint32(cls, keyval, keymask, keyoff, keyoffmask);

    rtnl_u32_set_hashmask(cls, hmask, hoffset);

    rtnl_u32_set_link(cls, htlink);

    rtnl_u32_add_action(cls, act);

    rtnl_u32_add_action(cls, act2);


    if ((err = rtnl_cls_add(sock, cls, NLM_F_CREATE))) {
        printf("Can not add classifier: %s\n", nl_geterror(err));
        return -1;
    }
    rtnl_cls_put(cls);
    return 0;
}
/* 
 * function that creates a new hash table 
 */
static
int u32_add_ht(struct nl_sock *sock, struct rtnl_link *rtnlLink, uint32_t prio, uint32_t htid, uint32_t divisor)
{

    int err;
    struct rtnl_cls *cls;

    cls=rtnl_cls_alloc();
    if (!(cls)) {
        printf("Can not allocate classifier\n");
        nl_socket_free(sock);
        exit(1);
    }
    
    rtnl_tc_set_link(TC_CAST(cls), rtnlLink);

    if ((err = rtnl_tc_set_kind(TC_CAST(cls), "u32"))) {
        printf("Can not set classifier as u32\n");
        return 1;
    }

    rtnl_cls_set_prio(cls, prio);
    rtnl_cls_set_protocol(cls, ETH_P_IP);
    rtnl_tc_set_parent(TC_CAST(cls), TC_HANDLE(0xffff, 0));

    rtnl_u32_set_handle(cls, htid, 0x0, 0x0);
    //printf("htid: 0x%X\n", htid);
    rtnl_u32_set_divisor(cls, divisor);

    if ((err = rtnl_cls_add(sock, cls, NLM_F_CREATE))) {
        printf("Can not add classifier: %s\n", nl_geterror(err));
        return -1;
    }
    rtnl_cls_put(cls);
    return 0;
}
예제 #6
0
파일: icmp.cpp 프로젝트: CodeTickler/mesos
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();
}