Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing ')' #537

Closed
valkum opened this issue May 11, 2016 · 4 comments · Fixed by #1006
Closed

Missing ')' #537

valkum opened this issue May 11, 2016 · 4 comments · Fixed by #1006
Assignees

Comments

@valkum
Copy link
Contributor

valkum commented May 11, 2016

Hello again, this time with a real bug, I think.

/virtual/main.c:66:83: error: expected ')'
        bpf_dins_pkt(skb, (u64)ip+12, 0, 32, ibpf_dext_pkt(skb, (u64)ip+16, 0, 32);
                                                                                  ^
/virtual/main.c:66:21: note: to match this '('
        bpf_dins_pkt(skb, (u64)ip+12, 0, 32, ibpf_dext_pkt(skb, (u64)ip+16, 0, 32);

Here is a sample program that is causing the error.

#include <uapi/linux/bpf.h>
#include <uapi/linux/if_ether.h>
#include <uapi/linux/if_packet.h>
#include <uapi/linux/ip.h>
#include <uapi/linux/in.h>
#include <uapi/linux/udp.h>
#include <bcc/proto.h>

#define ETH_LEN 14

struct dns_hdr_t
{
    uint16_t id;
    uint16_t flags;
    uint16_t qdcount;
    uint16_t ancount;
    uint16_t nscount;
    uint16_t arcount;
} BPF_PACKET_HEADER;


struct dns_query_flags_t
{
  uint16_t qtype;
  uint16_t qclass;
} BPF_PACKET_HEADER;

struct dns_char_t
{
    char c;
} BPF_PACKET_HEADER;

struct Key {
  unsigned char p[32];
};

struct Leaf {
  // Not really needed in this example
  unsigned char p[4];
};

BPF_TABLE("hash", struct Key, struct Leaf, cache, 128);

int dns_test(struct __sk_buff *skb)
{
  u8 *cursor = 0;
  struct Key key = {};
  struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
  if(ethernet->type == ETH_P_IP) {

    struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
    u16 hlen_bytes = ip->hlen << 2;
    if(ip->nextp == IPPROTO_UDP) {

      struct udp_t *udp = cursor_advance(cursor, sizeof(*udp));
      if(udp->dport == 53){
        u8 *sentinel = cursor + udp->length - sizeof(*udp) - 4;

        struct dns_hdr_t *dns_hdr = cursor_advance(cursor, sizeof(*dns_hdr));
        if((dns_hdr->flags >>15) != 0) {
          return -1;
        }
         // Error is happening here.
          ip->src = ip->dst;
          return 0;
      }
    }
  }

  return -1;
}
@drzaeus77 drzaeus77 self-assigned this May 11, 2016
@drzaeus77
Copy link
Collaborator

This is a rewriter deficiency. Workaround until this issue is fixed should be to do:

u32 tmp_dst = ip->dst;
ip->src = tmp_dst;

@mauriciovasquezbernal
Copy link
Contributor

Hi @drzaeus77, there are also some issues when defines are used:

#include <bcc/proto.h>

#define ETHERNET_BROADCAST 0xffffffffffff

int http_filter(struct __sk_buff *skb) {
    u8 *cursor = 0;
    struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
    ethernet->src = ETHERNET_BROADCAST;
    return -1;
}

fails to compile with the following error:

/virtual/main.c:14:44: error: expected expression
        bpf_dins_pkt(skb, (u64)ethernet+6, 0, 48, )     ethernet->src = ETHERNET_BROADCAST;

A workaround is to enclose the define in parentheses:

ethernet->src = (ETHERNET_BROADCAST);

PD: please ignore any possible verifier error on this example, I created it only to illustrate this bcc issue.

@tu-nv
Copy link
Contributor

tu-nv commented May 24, 2020

Today I faced the error when both rewriter and macro are used. Master branch, ubuntu 19.10, kernel 5.3. I think this is an error, although the parentheses trick does work.

#include <linux/if_ether.h>
#include <bcc/proto.h>
#include <uapi/linux/pkt_cls.h>

#define PKT_LEN_ADD 1


int mon_ingress(struct __sk_buff *skb) {

    u8 *cursor = 0;

    struct ethernet_t *eth = cursor_advance(cursor, sizeof(*eth));
    if (eth->type != ETH_P_IP) {
        return TC_ACT_OK;
    }

    struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));

    ip->tlen += PKT_LEN_ADD;

    return TC_ACT_OK;
}

and the error:

/virtual/main.c:31:52: error: expected ')'
    bpf_dins_pkt(skb, (u64)ip+2, 0, 16, PKT_LEN_ADD;
                                                   ^
/virtual/main.c:31:17: note: to match this '('
    bpf_dins_pkt(skb, (u64)ip+2, 0, 16, PKT_LEN_ADD;
                ^
1 error generated.

yonghong-song added a commit that referenced this issue May 26, 2020
Fix issue #537.

The bcc rewriter does not have enough information to do
proper rewriting from:
  #define PKT_LEN_ADD 1
  ip->tlen += PKT_LEN_ADD;
to
  bpf_dins_pkt(skb, (u64)ip+2, 0, 16, PKT_LEN_ADD);

So instead of generate incorrect code
which caused compilation error. Let return an error
earlier with helper comments so users know what to do.
With this patch, we will have
 /virtual/main.c:20:17: error: cannot have macro at the end of expresssion,
 workaround: put perentheses around macro "(MARCO)"
    ip->tlen += PKT_LEN_ADD;
                ^
@yonghong-song
Copy link
Collaborator

The bcc does not have enough information to do rewrite. So let us explicitly warn user the issues instead of silently generating incorrect code.
#2936

yonghong-song added a commit that referenced this issue May 26, 2020
Fix issue #537.

The bcc rewriter does not have enough information to do
proper rewriting from:
  #define PKT_LEN_ADD 1
  ip->tlen += PKT_LEN_ADD;
to
  bpf_dins_pkt(skb, (u64)ip+2, 0, 16, PKT_LEN_ADD);

So instead of generate incorrect code
which caused compilation error. Let return an error
earlier with helper comments so users know what to do.
With this patch, we will have
 /virtual/main.c:20:17: error: cannot have macro at the end of expresssion,
 workaround: put perentheses around macro "(MARCO)"
    ip->tlen += PKT_LEN_ADD;
                ^
CrackerCat pushed a commit to CrackerCat/bcc that referenced this issue Jul 31, 2024
Fix issue iovisor#537.

The bcc rewriter does not have enough information to do
proper rewriting from:
  #define PKT_LEN_ADD 1
  ip->tlen += PKT_LEN_ADD;
to
  bpf_dins_pkt(skb, (u64)ip+2, 0, 16, PKT_LEN_ADD);

So instead of generate incorrect code
which caused compilation error. Let return an error
earlier with helper comments so users know what to do.
With this patch, we will have
 /virtual/main.c:20:17: error: cannot have macro at the end of expresssion,
 workaround: put perentheses around macro "(MARCO)"
    ip->tlen += PKT_LEN_ADD;
                ^
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants