Are the named pipe created by `mknod` and the FIFO created by `mkfifo` equivalent?

Yes, it's equivalent, but obviously only if you tell mknod to actually create a FIFO, and not a block or character device (rarely done these days as devtmpfs/udev does it for you).

mkfifo foobar
# same difference
mknod foobar p

In strace it's identical for both commands:

mknod("foobar", S_IFIFO|0666)           = 0

So in terms of syscalls, mkfifo is actually shorthand for mknod.

The biggest difference, then, is in semantics. With mkfifo you can create a bunch of FIFOs in one go:

mkfifo a b c

With mknod, since you have to specify the type, it only ever accepts one argument:

# wrong:
$ mknod a b c p
mknod: invalid major device number ‘c’
# right:
mknod a p
mknod b p
mknod c p

In general, mknod can be difficult to use correctly. So if you want to work with FIFO, stick to mkfifo.

They are equivalent except at the extreme edges of portability. mknod ... p was originally the only way to create named pipes, but POSIX chose to omit it and invent mkfifo instead, presumably because named pipes are an inherently more portable concept than all that other stuff mknod can do with devices and their major and minor numbers. The mknod system call was also left out of the early verions of POSIX.

So, for portability to ancient UNIX, mknod ... p is better. For modern systems, mkfifo is slightly better, although it's pretty unlikely that you'll find an actual modern unix where mknod ... p doesn't work.