It's not possible directly, but you can use the va_list type to wrap the full complement of values and pass them to a version of the function that takes such an argument. Basically, break f2() into:
void f2v(int v1, va_list args) {
    // ...
    // use va_arg() repeatedly to get the various arguments here
}
void f2(int v1, ...) {
    va_list args;
    va_start(args, v1);
    f2v(v1, args);
    va_end(args);
}
And then rework f1() to use f2v() instead of f2():
void f1(int p1, int v1, ...) {
    // do whatever else you need to do before the call to f2
    va_list args;
    va_start(args, v1);
    f2v(v1, args);
    va_end(args);
    // do whatever else you need to do after the call to f2
}
This is, in theory, how printf() and vprintf() work--printf() internally can call vprintf() so that two functionally identical implementations are not needed.
(Don't forget--you need to #include <stdarg.h> to get access to va_list, va_start(), etc.)