]> git.proxmox.com Git - mirror_iproute2.git/blobdiff - misc/ssfilter.y
ss: Make leading ":" always optional for sport and dport
[mirror_iproute2.git] / misc / ssfilter.y
index 0413dddaa7584c5add220e899cbd544869dd3aa8..8e16b44638f6078e237fb3796d864708046b7072 100644 (file)
@@ -12,7 +12,14 @@ typedef struct ssfilter * ssfilter_t;
 
 static struct ssfilter * alloc_node(int type, void *pred)
 {
-       struct ssfilter *n = malloc(sizeof(*n));
+       struct ssfilter *n;
+
+       if (!ssfilter_is_supported(type)) {
+               fprintf(stderr, "It looks like such filter is not supported! Too old kernel?\n");
+               exit(-1);
+       }
+
+       n = malloc(sizeof(*n));
        if (n == NULL)
                abort();
        n->type = type;
@@ -36,7 +43,7 @@ static void yyerror(char *s)
 
 %}
 
-%token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND DEVCOND DEVNAME MARKMASK FWMARK
+%token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND DEVCOND DEVNAME MARKMASK FWMARK CGROUPCOND CGROUPPATH
 %left '|'
 %left '&'
 %nonassoc '!'
@@ -54,10 +61,6 @@ null:   /* NOTHING */ { $$ = NULL; }
         ;
 
 exprlist: expr
-        | '!' expr
-        {
-                $$ = alloc_node(SSF_NOT, $2);
-        }
         | exprlist '|' expr
         {
                 $$ = alloc_node(SSF_OR, $1);
@@ -83,6 +86,10 @@ expr:        '(' exprlist ')'
        {
                $$ = $2;
        }
+       | '!' expr
+       {
+               $$ = alloc_node(SSF_NOT, $2);
+       }
        | DCOND eq HOSTCOND
         {
                $$ = alloc_node(SSF_DCOND, $3);
@@ -156,6 +163,14 @@ expr:      '(' exprlist ')'
         {
                 $$ = alloc_node(SSF_NOT, alloc_node(SSF_MARKMASK, $3));
         }
+        | CGROUPPATH eq CGROUPCOND
+        {
+                $$ = alloc_node(SSF_CGROUPCOND, $3);
+        }
+        | CGROUPPATH NEQ CGROUPCOND
+        {
+                $$ = alloc_node(SSF_NOT, alloc_node(SSF_CGROUPCOND, $3));
+        }
         | AUTOBOUND
         {
                 $$ = alloc_node(SSF_S_AUTO, NULL);
@@ -276,6 +291,10 @@ int yylex(void)
                tok_type = FWMARK;
                return FWMARK;
        }
+       if (strcmp(curtok, "cgroup") == 0) {
+               tok_type = CGROUPPATH;
+               return CGROUPPATH;
+       }
        if (strcmp(curtok, ">=") == 0 ||
            strcmp(curtok, "ge") == 0 ||
            strcmp(curtok, "geq") == 0)
@@ -318,6 +337,14 @@ int yylex(void)
                }
                return MARKMASK;
        }
+       if (tok_type == CGROUPPATH) {
+               yylval = (void*)parse_cgroupcond(curtok);
+               if (yylval == NULL) {
+                       fprintf(stderr, "Cannot parse cgroup %s.\n", curtok);
+                       exit(1);
+               }
+               return CGROUPCOND;
+       }
        yylval = (void*)parse_hostcond(curtok, tok_type == SPORT || tok_type == DPORT);
        if (yylval == NULL) {
                fprintf(stderr, "Cannot parse dst/src address.\n");